mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +00:00
feat: api接口新增access_token校验
This commit is contained in:
@@ -103,6 +103,8 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
const [whisperProgressData, setWhisperProgressData] = useState<{ downloaded: number; total: number; speed: number }>({ downloaded: 0, total: 0, speed: 0 })
|
||||
const [whisperModelStatus, setWhisperModelStatus] = useState<{ exists: boolean; modelPath?: string; tokensPath?: string } | null>(null)
|
||||
|
||||
const [httpApiToken, setHttpApiToken] = useState('')
|
||||
|
||||
const formatBytes = (bytes: number) => {
|
||||
if (bytes === 0) return '0 B';
|
||||
const k = 1024;
|
||||
@@ -111,6 +113,23 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
};
|
||||
|
||||
const generateRandomToken = async () => {
|
||||
// 生成 32 字符的十六进制随机字符串 (16 bytes)
|
||||
const array = new Uint8Array(16)
|
||||
crypto.getRandomValues(array)
|
||||
const token = Array.from(array).map(b => b.toString(16).padStart(2, '0')).join('')
|
||||
|
||||
setHttpApiToken(token)
|
||||
await configService.setHttpApiToken(token)
|
||||
showMessage('已生成并保存新的 Access Token', true)
|
||||
}
|
||||
|
||||
const clearApiToken = async () => {
|
||||
setHttpApiToken('')
|
||||
await configService.setHttpApiToken('')
|
||||
showMessage('已清除 Access Token,API 将允许无鉴权访问', true)
|
||||
}
|
||||
|
||||
const [autoTranscribeVoice, setAutoTranscribeVoice] = useState(false)
|
||||
const [transcribeLanguages, setTranscribeLanguages] = useState<string[]>(['zh'])
|
||||
|
||||
@@ -192,6 +211,8 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
checkWaylandStatus()
|
||||
}, [])
|
||||
|
||||
|
||||
|
||||
// 检查 Hello 可用性
|
||||
useEffect(() => {
|
||||
setHelloAvailable(isWindows)
|
||||
@@ -319,6 +340,10 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
const savedAuthEnabled = await window.electronAPI.auth.verifyEnabled()
|
||||
const savedAuthUseHello = await configService.getAuthUseHello()
|
||||
const savedIsLockMode = await window.electronAPI.auth.isLockMode()
|
||||
|
||||
const savedHttpApiToken = await configService.getHttpApiToken()
|
||||
if (savedHttpApiToken) setHttpApiToken(savedHttpApiToken)
|
||||
|
||||
setAuthEnabled(savedAuthEnabled)
|
||||
setAuthUseHello(savedAuthUseHello)
|
||||
setIsLockMode(savedIsLockMode)
|
||||
@@ -1901,6 +1926,36 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label>Access Token (鉴权凭证)</label>
|
||||
<span className="form-hint">
|
||||
设置后,请求头需携带 <code>Authorization: Bearer <token></code>,
|
||||
或者参数中携带 <code>?access_token=<token></code>
|
||||
</span>
|
||||
<div style={{ display: 'flex', gap: '8px', marginTop: '8px' }}>
|
||||
<input
|
||||
type="text"
|
||||
className="field-input"
|
||||
value={httpApiToken}
|
||||
placeholder="留空表示不验证 Token"
|
||||
onChange={(e) => {
|
||||
const val = e.target.value
|
||||
setHttpApiToken(val)
|
||||
scheduleConfigSave('httpApiToken', () => configService.setHttpApiToken(val))
|
||||
}}
|
||||
style={{ flex: 1, fontFamily: 'monospace' }}
|
||||
/>
|
||||
<button className="btn btn-secondary" onClick={generateRandomToken}>
|
||||
<RefreshCw size={14} style={{ marginRight: 4 }} /> 随机生成
|
||||
</button>
|
||||
{httpApiToken && (
|
||||
<button className="btn btn-danger" onClick={clearApiToken} title="清除 Token">
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{httpApiRunning && (
|
||||
<div className="form-group">
|
||||
<label>API 地址</label>
|
||||
@@ -1956,18 +2011,18 @@ function SettingsPage({ onClose }: SettingsPageProps = {}) {
|
||||
<span className="form-hint">外部软件连接这个 SSE 地址即可接收新消息推送;需要先开启上方 `HTTP API 服务`</span>
|
||||
<div className="api-url-display">
|
||||
<input
|
||||
type="text"
|
||||
className="field-input"
|
||||
value={`http://127.0.0.1:${httpApiPort}/api/v1/push/messages`}
|
||||
readOnly
|
||||
type="text"
|
||||
className="field-input"
|
||||
value={`http://127.0.0.1:${httpApiPort}/api/v1/push/messages${httpApiToken ? `?access_token=${httpApiToken}` : ''}`}
|
||||
readOnly
|
||||
/>
|
||||
<button
|
||||
className="btn btn-secondary"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(`http://127.0.0.1:${httpApiPort}/api/v1/push/messages`)
|
||||
showMessage('已复制推送地址', true)
|
||||
}}
|
||||
title="复制"
|
||||
className="btn btn-secondary"
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(`http://127.0.0.1:${httpApiPort}/api/v1/push/messages${httpApiToken ? `?access_token=${httpApiToken}` : ''}`)
|
||||
showMessage('已复制推送地址', true)
|
||||
}}
|
||||
title="复制"
|
||||
>
|
||||
<Copy size={16} />
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user