mirror of
https://github.com/langgenius/dify.git
synced 2026-04-05 19:59:21 +08:00
refactor: replace localStorage with HTTP-only cookies for auth tokens (#24365)
Signed-off-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Signed-off-by: lyzno1 <yuanyouhuilyz@gmail.com> Signed-off-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Yunlu Wen <wylswz@163.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: GareArc <chen4851@purdue.edu> Co-authored-by: NFish <douxc512@gmail.com> Co-authored-by: Davide Delbianco <davide.delbianco@outlook.com> Co-authored-by: minglu7 <1347866672@qq.com> Co-authored-by: Ponder <ruan.lj@foxmail.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: heyszt <270985384@qq.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Guangdong Liu <liugddx@gmail.com> Co-authored-by: Eric Guo <eric.guocz@gmail.com> Co-authored-by: NeatGuyCoding <15627489+NeatGuyCoding@users.noreply.github.com> Co-authored-by: XlKsyt <caixuesen@outlook.com> Co-authored-by: Dhruv Gorasiya <80987415+DhruvGorasiya@users.noreply.github.com> Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: lyzno1 <92089059+lyzno1@users.noreply.github.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: GuanMu <ballmanjq@gmail.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Tonlo <123lzs123@gmail.com> Co-authored-by: Yusuke Yamada <yamachu.dev@gmail.com> Co-authored-by: Novice <novice12185727@gmail.com> Co-authored-by: kenwoodjw <blackxin55+@gmail.com> Co-authored-by: Ademílson Tonato <ademilsonft@outlook.com> Co-authored-by: znn <jubinkumarsoni@gmail.com> Co-authored-by: yangzheli <43645580+yangzheli@users.noreply.github.com>
This commit is contained in:
@@ -2,9 +2,9 @@ import type { AfterResponseHook, BeforeErrorHook, BeforeRequestHook, Hooks } fro
|
||||
import ky from 'ky'
|
||||
import type { IOtherOptions } from './base'
|
||||
import Toast from '@/app/components/base/toast'
|
||||
import { API_PREFIX, APP_VERSION, MARKETPLACE_API_PREFIX, PUBLIC_API_PREFIX } from '@/config'
|
||||
import { getInitialTokenV2, isTokenV1 } from '@/app/components/share/utils'
|
||||
import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils'
|
||||
import { API_PREFIX, APP_VERSION, CSRF_COOKIE_NAME, CSRF_HEADER_NAME, MARKETPLACE_API_PREFIX, PASSPORT_HEADER_NAME, PUBLIC_API_PREFIX, WEB_APP_SHARE_CODE_HEADER_NAME } from '@/config'
|
||||
import Cookies from 'js-cookie'
|
||||
import { getWebAppAccessToken, getWebAppPassport } from './webapp-auth'
|
||||
|
||||
const TIME_OUT = 100000
|
||||
|
||||
@@ -69,35 +69,15 @@ const beforeErrorToast = (otherOptions: IOtherOptions): BeforeErrorHook => {
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAccessToken(isPublicAPI?: boolean) {
|
||||
if (isPublicAPI) {
|
||||
const sharedToken = globalThis.location.pathname.split('/').slice(-1)[0]
|
||||
const userId = (await getProcessedSystemVariablesFromUrlParams()).user_id
|
||||
const accessToken = localStorage.getItem('token') || JSON.stringify({ version: 2 })
|
||||
let accessTokenJson: Record<string, any> = { version: 2 }
|
||||
try {
|
||||
accessTokenJson = JSON.parse(accessToken)
|
||||
if (isTokenV1(accessTokenJson))
|
||||
accessTokenJson = getInitialTokenV2()
|
||||
}
|
||||
catch {
|
||||
|
||||
}
|
||||
return accessTokenJson[sharedToken]?.[userId || 'DEFAULT']
|
||||
}
|
||||
else {
|
||||
return localStorage.getItem('console_token') || ''
|
||||
}
|
||||
}
|
||||
|
||||
const beforeRequestPublicAuthorization: BeforeRequestHook = async (request) => {
|
||||
const token = await getAccessToken(true)
|
||||
request.headers.set('Authorization', `Bearer ${token}`)
|
||||
}
|
||||
|
||||
const beforeRequestAuthorization: BeforeRequestHook = async (request) => {
|
||||
const accessToken = await getAccessToken()
|
||||
request.headers.set('Authorization', `Bearer ${accessToken}`)
|
||||
const beforeRequestPublicWithCode = (request: Request) => {
|
||||
request.headers.set('Authorization', `Bearer ${getWebAppAccessToken()}`)
|
||||
const shareCode = globalThis.location.pathname.split('/').filter(Boolean).pop() || ''
|
||||
// some pages does not end with share code, so we need to check it
|
||||
// TODO: maybe find a better way to access app code?
|
||||
if (shareCode === 'webapp-signin' || shareCode === 'check-code')
|
||||
return
|
||||
request.headers.set(WEB_APP_SHARE_CODE_HEADER_NAME, shareCode)
|
||||
request.headers.set(PASSPORT_HEADER_NAME, getWebAppPassport(shareCode))
|
||||
}
|
||||
|
||||
const baseHooks: Hooks = {
|
||||
@@ -148,6 +128,8 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
|
||||
}
|
||||
|
||||
const fetchPathname = base + (url.startsWith('/') ? url : `/${url}`)
|
||||
if (!isMarketplaceAPI)
|
||||
(headers as any).set(CSRF_HEADER_NAME, Cookies.get(CSRF_COOKIE_NAME()) || '')
|
||||
|
||||
if (deleteContentType)
|
||||
(headers as any).delete('Content-Type')
|
||||
@@ -165,8 +147,7 @@ async function base<T>(url: string, options: FetchOptionType = {}, otherOptions:
|
||||
],
|
||||
beforeRequest: [
|
||||
...baseHooks.beforeRequest || [],
|
||||
isPublicAPI && beforeRequestPublicAuthorization,
|
||||
!isPublicAPI && !isMarketplaceAPI && beforeRequestAuthorization,
|
||||
isPublicAPI && beforeRequestPublicWithCode,
|
||||
].filter((h): h is BeforeRequestHook => Boolean(h)),
|
||||
afterResponse: [
|
||||
...baseHooks.afterResponse || [],
|
||||
|
||||
Reference in New Issue
Block a user