新增 token 验证
This commit is contained in:
parent
fbbefe0a63
commit
b51b8de460
@ -23,6 +23,10 @@ class TokenCreate(BaseModel):
|
||||
agent_id: str
|
||||
name: str
|
||||
|
||||
class TokenVerify(BaseModel):
|
||||
agent_id: str
|
||||
token: str
|
||||
|
||||
class TokenResponse(BaseModel):
|
||||
id: int
|
||||
agent_id: str
|
||||
@ -80,4 +84,20 @@ async def delete_token(token_id: int, db: Session = Depends(get_db)):
|
||||
db.delete(token)
|
||||
db.commit()
|
||||
|
||||
return {"success": True, "message": "Token deleted"}
|
||||
return {"success": True, "message": "Token deleted"}
|
||||
|
||||
@admin.post("/verify_token")
|
||||
async def verify_agent_token(
|
||||
token_data: TokenVerify,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""验证智能体访问令牌"""
|
||||
token = db.query(AgentToken).filter(
|
||||
AgentToken.agent_id == token_data.agent_id,
|
||||
AgentToken.token == token_data.token
|
||||
).first()
|
||||
|
||||
if not token:
|
||||
raise HTTPException(status_code=401, detail="Invalid token")
|
||||
|
||||
return {"success": True, "message": "Token verified"}
|
||||
@ -6,47 +6,15 @@ import uuid
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException
|
||||
from fastapi.responses import StreamingResponse
|
||||
from langchain_core.messages import AIMessageChunk
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from src import executor, config, retriever
|
||||
from src.core import HistoryManager
|
||||
from src.agents import agent_manager
|
||||
from src.models import select_model
|
||||
from src.utils.logging_config import logger
|
||||
from src.utils.db_manager import db_manager
|
||||
from src.models.token_model import AgentToken
|
||||
|
||||
chat = APIRouter(prefix="/chat")
|
||||
|
||||
# 依赖项:获取数据库会话
|
||||
def get_db():
|
||||
db = db_manager.get_session()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
class TokenVerify(BaseModel):
|
||||
agent_id: str
|
||||
token: str
|
||||
|
||||
@chat.post("/verify_token")
|
||||
async def verify_agent_token(
|
||||
token_data: TokenVerify,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""验证智能体访问令牌"""
|
||||
token = db.query(AgentToken).filter(
|
||||
AgentToken.agent_id == token_data.agent_id,
|
||||
AgentToken.token == token_data.token
|
||||
).first()
|
||||
|
||||
if not token:
|
||||
raise HTTPException(status_code=401, detail="Invalid token")
|
||||
|
||||
return {"success": True, "message": "Token verified"}
|
||||
|
||||
@chat.get("/")
|
||||
async def chat_get():
|
||||
return "Chat Get!"
|
||||
|
||||
@ -1,9 +1,8 @@
|
||||
<template>
|
||||
<div class="token-manager">
|
||||
<h2 class="manager-title">访问令牌管理</h2>
|
||||
<div class="token-tools">
|
||||
<a-button type="primary" size="small" @click="showAddTokenModal">
|
||||
<PlusOutlined /> 创建令牌
|
||||
<PlusOutlined /> 创建 Token
|
||||
</a-button>
|
||||
</div>
|
||||
<!-- 令牌列表 -->
|
||||
@ -190,7 +189,7 @@ onMounted(() => {
|
||||
<style lang="less" scoped>
|
||||
.token-manager {
|
||||
margin-top: 1rem;
|
||||
padding: 0 0.5rem;
|
||||
// padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.manager-title {
|
||||
@ -207,6 +206,12 @@ onMounted(() => {
|
||||
.token-list {
|
||||
max-height: calc(100vh - 400px);
|
||||
overflow-y: auto;
|
||||
li.ant-list-item {
|
||||
background-color: var(--gray-100);
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.token-item {
|
||||
|
||||
@ -53,7 +53,7 @@ const router = createRouter({
|
||||
{
|
||||
path: '/agent/:agent_id',
|
||||
name: 'AgentSinglePage',
|
||||
component: () => import('../components/AgentChatComponent.vue'),
|
||||
component: () => import('../views/AgentSingleView.vue'),
|
||||
},
|
||||
{
|
||||
path: '/graph',
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
<div class="agent-single-view">
|
||||
<!-- Token验证弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="tokenModalVisible"
|
||||
v-model:open="tokenModalVisible"
|
||||
title="访问验证"
|
||||
:closable="false"
|
||||
:maskClosable="false"
|
||||
:keyboard="false"
|
||||
:footer="null"
|
||||
width="500px"
|
||||
>
|
||||
<div class="token-verify-form">
|
||||
<p>需要输入访问令牌才能使用该智能体</p>
|
||||
@ -56,7 +57,7 @@ const verifyToken = async () => {
|
||||
errorMessage.value = '';
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/chat/verify_token', {
|
||||
const response = await fetch('/api/admin/verify_token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
@ -72,8 +73,8 @@ const verifyToken = async () => {
|
||||
isVerified.value = true;
|
||||
tokenModalVisible.value = false;
|
||||
|
||||
// 保存验证状态到localStorage
|
||||
localStorage.setItem(`agent-token-verified-${agentId.value}`, 'true');
|
||||
// 保存令牌到localStorage
|
||||
localStorage.setItem(`agent-token-${agentId.value}`, tokenInput.value);
|
||||
} else {
|
||||
// 验证失败
|
||||
const data = await response.json();
|
||||
@ -88,11 +89,42 @@ const verifyToken = async () => {
|
||||
};
|
||||
|
||||
// 检查是否已经验证
|
||||
const checkVerification = () => {
|
||||
const verified = localStorage.getItem(`agent-token-verified-${agentId.value}`);
|
||||
if (verified === 'true') {
|
||||
isVerified.value = true;
|
||||
const checkVerification = async () => {
|
||||
const savedToken = localStorage.getItem(`agent-token-${agentId.value}`);
|
||||
|
||||
if (savedToken) {
|
||||
// 即使有保存的令牌,也要重新验证其有效性
|
||||
verifying.value = true;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/admin/verify_token', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
agent_id: agentId.value,
|
||||
token: savedToken
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
// 验证成功
|
||||
isVerified.value = true;
|
||||
tokenInput.value = savedToken; // 保存已验证的令牌到输入框
|
||||
} else {
|
||||
// 令牌无效,清除本地存储并显示输入框
|
||||
localStorage.removeItem(`agent-token-${agentId.value}`);
|
||||
tokenModalVisible.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('验证令牌出错:', error);
|
||||
tokenModalVisible.value = true;
|
||||
} finally {
|
||||
verifying.value = false;
|
||||
}
|
||||
} else {
|
||||
// 没有保存的令牌,显示输入框
|
||||
tokenModalVisible.value = true;
|
||||
}
|
||||
};
|
||||
@ -122,7 +154,7 @@ onMounted(() => {
|
||||
|
||||
.token-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
justify-content: space-between;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,11 +89,15 @@
|
||||
打开智能体配置
|
||||
</a-button>
|
||||
|
||||
<!-- 添加Token管理组件 -->
|
||||
<div class="token-section">
|
||||
<TokenManagerComponent :agent-id="selectedAgentId" />
|
||||
</div>
|
||||
|
||||
<!-- 添加令牌管理按钮 -->
|
||||
<a-button
|
||||
style="margin-top: 16px;"
|
||||
type="primary"
|
||||
block
|
||||
@click="openTokenModal"
|
||||
>
|
||||
访问令牌管理
|
||||
</a-button>
|
||||
</div>
|
||||
<div v-else class="no-agent-selected">
|
||||
请先选择一个智能体
|
||||
@ -155,6 +159,17 @@
|
||||
</a-form>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 令牌管理弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="state.tokenModalVisible"
|
||||
title="访问令牌管理"
|
||||
width="650px"
|
||||
:footer="null"
|
||||
@cancel="closeTokenModal"
|
||||
>
|
||||
<TokenManagerComponent v-if="selectedAgentId" :agent-id="selectedAgentId" />
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -179,6 +194,7 @@ const state = reactive({
|
||||
isSidebarOpen: JSON.parse(localStorage.getItem('agent-sidebar-open') || 'true'),
|
||||
isConfigSidebarOpen: false,
|
||||
configModalVisible: false,
|
||||
tokenModalVisible: false,
|
||||
isEmptyConfig: computed(() =>
|
||||
!selectedAgentId.value ||
|
||||
Object.keys(configurableItems.value).length === 0
|
||||
@ -205,6 +221,16 @@ const closeConfigModal = () => {
|
||||
state.configModalVisible = false;
|
||||
};
|
||||
|
||||
// 打开令牌管理弹窗
|
||||
const openTokenModal = () => {
|
||||
state.tokenModalVisible = true;
|
||||
};
|
||||
|
||||
// 关闭令牌管理弹窗
|
||||
const closeTokenModal = () => {
|
||||
state.tokenModalVisible = false;
|
||||
};
|
||||
|
||||
// 根据选中的智能体加载配置
|
||||
const loadAgentConfig = () => {
|
||||
// BUG: 目前消息重置有问题,需要重置消息
|
||||
|
||||
Loading…
Reference in New Issue
Block a user