feat: request token
This commit is contained in:
parent
4c9efffd6d
commit
d4bfc53bbf
|
@ -4,7 +4,7 @@ import type * as Login from './types/login'
|
||||||
const loginURLs = {
|
const loginURLs = {
|
||||||
login: `/login/login`,
|
login: `/login/login`,
|
||||||
register: `/login/register`,
|
register: `/login/register`,
|
||||||
verificationCode: `/auth/email/send`,
|
verificationCode: `/auth/email/code`,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户登录数据
|
// 获取用户登录数据
|
||||||
|
|
|
@ -25,5 +25,4 @@ export type LoginResponseData = KUNGalgameResponseData<{
|
||||||
name: string
|
name: string
|
||||||
avatar: string
|
avatar: string
|
||||||
token: string
|
token: string
|
||||||
refreshToken: string
|
|
||||||
}>
|
}>
|
||||||
|
|
26
src/error/onRequestError.ts
Normal file
26
src/error/onRequestError.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// 全局消息组件(顶部)
|
||||||
|
import message from '@/components/alert/Message'
|
||||||
|
// 导入路由
|
||||||
|
import router from '@/router'
|
||||||
|
|
||||||
|
export function onRequestError(response: Response) {
|
||||||
|
if (response.status === 401) {
|
||||||
|
message(
|
||||||
|
'Login expired, please log in again.',
|
||||||
|
'登陆过期,请重新登陆',
|
||||||
|
'error'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status === 404) {
|
||||||
|
message(
|
||||||
|
'Not Found, request address is incorrect.',
|
||||||
|
'资源未找到,请求地址出错',
|
||||||
|
'error'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status === 500) {
|
||||||
|
message('Internal Server Error', '服务器遇到了未处理的错误', 'error')
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
import { Router } from 'vue-router'
|
// 导入 rooter
|
||||||
import { type RouteRecordRaw } from 'vue-router'
|
import { Router, RouteRecordRaw } from 'vue-router'
|
||||||
import { useKUNGalgameUserStore } from '@/store/modules/kungalgamer'
|
// 导入公共路由,无需鉴权
|
||||||
import { WHITE_LIST } from '../router'
|
import { WHITE_LIST } from '../router'
|
||||||
import { storeToRefs } from 'pinia'
|
// 导入获取 token 的函数
|
||||||
import { unref } from 'vue'
|
import { getToken } from '@/utils/cookie'
|
||||||
|
|
||||||
// 临时使用
|
// 临时使用
|
||||||
import { asyncRoutes } from '../router'
|
import { asyncRoutes } from '../router'
|
||||||
|
|
||||||
export const createPermission = (router: Router) => {
|
export const createPermission = (router: Router) => {
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
const useStore = useKUNGalgameUserStore()
|
// 获取当前 token,access token,refresh 在 服务器端 http only
|
||||||
const { token } = storeToRefs(useStore)
|
const token = getToken()
|
||||||
const getRoute = asyncRoutes
|
const getRoute = asyncRoutes
|
||||||
|
|
||||||
// 白名单
|
// 白名单
|
||||||
|
@ -21,7 +21,7 @@ export const createPermission = (router: Router) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 没有token
|
// 没有token
|
||||||
if (!unref(token)) {
|
if (!token) {
|
||||||
if (!to.meta?.permission && getRoute.length > 0) {
|
if (!to.meta?.permission && getRoute.length > 0) {
|
||||||
next()
|
next()
|
||||||
return
|
return
|
||||||
|
|
|
@ -22,7 +22,6 @@ interface UserState {
|
||||||
name: string
|
name: string
|
||||||
avatar: string
|
avatar: string
|
||||||
token: string
|
token: string
|
||||||
refreshToken: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 这里用了 pinia-plugin-persistedstate,直接存储 token 即可
|
// 这里用了 pinia-plugin-persistedstate,直接存储 token 即可
|
||||||
|
@ -35,7 +34,6 @@ export const useKUNGalgameUserStore = defineStore({
|
||||||
name: '',
|
name: '',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
token: '',
|
token: '',
|
||||||
refreshToken: '',
|
|
||||||
}),
|
}),
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -45,11 +43,6 @@ export const useKUNGalgameUserStore = defineStore({
|
||||||
this.name = name
|
this.name = name
|
||||||
this.avatar = avatar
|
this.avatar = avatar
|
||||||
},
|
},
|
||||||
// 设置用户 token
|
|
||||||
setToken(token: string, refreshToken: string): void {
|
|
||||||
this.token = token
|
|
||||||
setToken(refreshToken)
|
|
||||||
},
|
|
||||||
// 登陆
|
// 登陆
|
||||||
login(request: LoginRequestData): Promise<LoginResponseData> {
|
login(request: LoginRequestData): Promise<LoginResponseData> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -58,7 +51,7 @@ export const useKUNGalgameUserStore = defineStore({
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
this.setUserInfo(res.data.uid, res.data.name, res.data.avatar)
|
this.setUserInfo(res.data.uid, res.data.name, res.data.avatar)
|
||||||
this.setToken(res.data.token, res.data.refreshToken)
|
setToken(res.data.token)
|
||||||
} else
|
} else
|
||||||
(error: Error) => {
|
(error: Error) => {
|
||||||
throw new Error('500 Server ERROR', error)
|
throw new Error('500 Server ERROR', error)
|
||||||
|
@ -90,7 +83,7 @@ export const useKUNGalgameUserStore = defineStore({
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.data) {
|
if (res.data) {
|
||||||
this.setUserInfo(res.data.uid, res.data.name, res.data.avatar)
|
this.setUserInfo(res.data.uid, res.data.name, res.data.avatar)
|
||||||
this.setToken(res.data.token, res.data.refreshToken)
|
setToken(res.data.token)
|
||||||
} else
|
} else
|
||||||
(error: Error) => {
|
(error: Error) => {
|
||||||
throw new Error('500 Server ERROR', error)
|
throw new Error('500 Server ERROR', error)
|
||||||
|
|
|
@ -61,8 +61,8 @@ html {
|
||||||
|
|
||||||
--shadow: 0 1px 2px hsla(0, 0%, 0%, 0.05), 0 1px 4px hsla(0, 0%, 0%, 0.05),
|
--shadow: 0 1px 2px hsla(0, 0%, 0%, 0.05), 0 1px 4px hsla(0, 0%, 0%, 0.05),
|
||||||
0 2px 8px hsla(0, 0%, 0%, 0.05);
|
0 2px 8px hsla(0, 0%, 0%, 0.05);
|
||||||
--kungalgame-shadow-0: 5px 5px 7px var(--kungalgame-blue-1),
|
--kungalgame-shadow-0: 5px 5px 10px var(--kungalgame-trans-blue-1),
|
||||||
-5px -5px 10px var(--kungalgame-blue-1);
|
-5px -5px 10px var(--kungalgame-trans-blue-1);
|
||||||
--kungalgame-shadow-1: 2px 2px 4px var(--kungalgame-blue-1),
|
--kungalgame-shadow-1: 2px 2px 4px var(--kungalgame-blue-1),
|
||||||
-2px -2px 4px var(--kungalgame-blue-1);
|
-2px -2px 4px var(--kungalgame-blue-1);
|
||||||
--kungalgame-shadow-2: inset 1px 1px 2px var(--kungalgame-blue-1),
|
--kungalgame-shadow-2: inset 1px 1px 2px var(--kungalgame-blue-1),
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// 操作 cookie 的函数
|
// 操作 cookie 的函数
|
||||||
import { getToken } from '@/utils/cookie'
|
import { getToken } from '@/utils/cookie'
|
||||||
|
// 错误处理函数
|
||||||
|
import { onRequestError } from '@/error/onRequestError'
|
||||||
|
|
||||||
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
|
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
|
||||||
|
|
||||||
|
@ -13,22 +15,22 @@ const fetchRequest = async <T>(
|
||||||
url: string,
|
url: string,
|
||||||
options: FetchOptions
|
options: FetchOptions
|
||||||
): Promise<T> => {
|
): Promise<T> => {
|
||||||
try {
|
|
||||||
const baseUrl = import.meta.env.VITE_API_BASE_URL
|
const baseUrl = import.meta.env.VITE_API_BASE_URL
|
||||||
const fullUrl = `${baseUrl}${url}`
|
const fullUrl = `${baseUrl}${url}`
|
||||||
|
|
||||||
const response = await fetch(fullUrl, options)
|
// 在请求头中添加 token
|
||||||
|
const headers = {
|
||||||
if (!response.ok) {
|
...options.headers,
|
||||||
throw new Error('Request Error!')
|
Authorization: `Bearer ${getToken()}`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const response = await fetch(fullUrl, { ...options, headers })
|
||||||
|
|
||||||
|
// 处理错误
|
||||||
|
onRequestError(response)
|
||||||
|
|
||||||
const data: T = await response.json()
|
const data: T = await response.json()
|
||||||
return data
|
return data
|
||||||
} catch (error) {
|
|
||||||
console.error('Fetch Error:', error)
|
|
||||||
throw new Error('Request Error!')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fetchGet = async <T>(
|
const fetchGet = async <T>(
|
||||||
|
|
|
@ -15,42 +15,42 @@ export default defineConfig({
|
||||||
'@': path.resolve(__dirname, './src'),
|
'@': path.resolve(__dirname, './src'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
server: {
|
// server: {
|
||||||
/** 是否开启 HTTPS */
|
// /** 是否开启 HTTPS */
|
||||||
https: false,
|
// https: false,
|
||||||
/** 设置 host: true 才可以使用 Network 的形式,以 IP 访问项目 */
|
// /** 设置 host: true 才可以使用 Network 的形式,以 IP 访问项目 */
|
||||||
host: true, // host: "0.0.0.0"
|
// host: '127.0.0.1', // host: "0.0.0.0"
|
||||||
/** 端口号 */
|
// /** 端口号 */
|
||||||
port: 1007,
|
// port: 1007,
|
||||||
/** 是否自动打开浏览器 */
|
// /** 是否自动打开浏览器 */
|
||||||
open: false,
|
// open: false,
|
||||||
/** 跨域设置允许 */
|
// /** 跨域设置允许 */
|
||||||
cors: true,
|
// cors: true,
|
||||||
/** 端口被占用时,是否直接退出 */
|
// /** 端口被占用时,是否直接退出 */
|
||||||
strictPort: true,
|
// strictPort: true,
|
||||||
/** 接口代理 */
|
// /** 接口代理 */
|
||||||
proxy: {},
|
// proxy: {},
|
||||||
},
|
// },
|
||||||
build: {
|
// build: {
|
||||||
/** 打包大小超过 500kb 警告 */
|
// /** 打包大小超过 500kb 警告 */
|
||||||
chunkSizeWarningLimit: 500,
|
// chunkSizeWarningLimit: 500,
|
||||||
/** Vite 2.6.x 以上需要配置 minify: "terser", terserOptions 才能生效 */
|
// /** Vite 2.6.x 以上需要配置 minify: "terser", terserOptions 才能生效 */
|
||||||
minify: 'terser',
|
// minify: 'terser',
|
||||||
/** 在打包代码时移除 console.log、debugger 和 注释 */
|
// /** 在打包代码时移除 console.log、debugger 和 注释 */
|
||||||
terserOptions: {
|
// terserOptions: {
|
||||||
compress: {
|
// compress: {
|
||||||
drop_console: false,
|
// drop_console: false,
|
||||||
drop_debugger: true,
|
// drop_debugger: true,
|
||||||
pure_funcs: ['console.log'],
|
// pure_funcs: ['console.log'],
|
||||||
},
|
// },
|
||||||
format: {
|
// format: {
|
||||||
/** 删除注释 */
|
// /** 删除注释 */
|
||||||
comments: false,
|
// comments: false,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
/** 打包后静态资源目录 */
|
// /** 打包后静态资源目录 */
|
||||||
assetsDir: 'kun',
|
// assetsDir: 'kun',
|
||||||
},
|
// },
|
||||||
// 消除 i18n 警告
|
// 消除 i18n 警告
|
||||||
define: {
|
define: {
|
||||||
__VUE_I18N_FULL_INSTALL__: true,
|
__VUE_I18N_FULL_INSTALL__: true,
|
||||||
|
|
Loading…
Reference in a new issue