feat: add query-login
This commit is contained in:
		| @@ -1,46 +1,26 @@ | ||||
| import MD5 from 'crypto-js/md5.js'; | ||||
| import { getBaseURL, query } from '../query.ts'; | ||||
| import { getBaseURL, queryLogin } from '../query.ts'; | ||||
| import { chalk } from '../chalk.ts'; | ||||
| import jsonwebtoken from 'jsonwebtoken'; | ||||
| import { BaseLoad } from '@kevisual/load'; | ||||
| import { getConfig, writeConfig } from '../get-config.ts'; | ||||
|  | ||||
| type LoginWithWebOptions = {}; | ||||
| export const loginWithWeb = async (opts?: LoginWithWebOptions) => { | ||||
|   const baseURL = getBaseURL(); | ||||
|   const randomId = Math.random().toString(36).substring(2, 15); | ||||
|   const timestamp = Date.now(); | ||||
|   const tokenSecret = 'xiao' + randomId; | ||||
|   const sign = MD5(`${tokenSecret}${timestamp}`).toString(); | ||||
|   const token = jsonwebtoken.sign({ randomId, timestamp, sign }, tokenSecret, { | ||||
|     // 10分钟过期 | ||||
|     expiresIn: 60 * 10, // 10分钟 | ||||
|   }); | ||||
|   const config = await getConfig(); | ||||
|  | ||||
|   const url = `${baseURL}/api/router?path=user&key=webLogin&p&loginToken=${token}&sign=${sign}&randomId=${randomId}`; | ||||
|  | ||||
|   console.log(chalk.blue(url)); | ||||
|   return { | ||||
|     url, | ||||
|     token, | ||||
|     tokenSecret, | ||||
|   }; | ||||
|   const res = queryLogin.loginWithWeb(baseURL, { MD5, jsonwebtoken }); | ||||
|   console.log(chalk.blue(res.url)); | ||||
|   return res; | ||||
| }; | ||||
|  | ||||
| type PollLoginOptions = { | ||||
|   tokenSecret: string; | ||||
|   saveToken?: any; | ||||
| }; | ||||
| export const pollLoginStatus = async (token: string, opts: PollLoginOptions) => { | ||||
|   const load = new BaseLoad(); | ||||
|   load.load( | ||||
|     async () => { | ||||
|       const res = await query.post({ | ||||
|         path: 'user', | ||||
|         key: 'checkLoginStatus', | ||||
|         loginToken: token, | ||||
|       }); | ||||
|       const res = await queryLogin.checkLoginStatus(token); | ||||
|       return res; | ||||
|     }, | ||||
|     { | ||||
| @@ -55,36 +35,21 @@ export const pollLoginStatus = async (token: string, opts: PollLoginOptions) => | ||||
|     timeout: 60 * 3 * 1000, // 5分钟超时 | ||||
|   }); | ||||
|   if (res.code === 200 && res.data?.code === 200) { | ||||
|     const data = res.data?.data; | ||||
|     try { | ||||
|       const payload = jsonwebtoken.verify(data, opts.tokenSecret) as UserPayload; | ||||
|       type UserPayload = { | ||||
|         userToken: { | ||||
|           token: string; | ||||
|           expireTime: number; | ||||
|         }; | ||||
|         user: { | ||||
|           id: string; | ||||
|           username: string; | ||||
|         }; | ||||
|       }; | ||||
|       const userToken = payload.userToken; | ||||
|       // console.log('token:\n\n', userToken); | ||||
|       console.log(chalk.green('网页登录成功', payload?.user?.username)); | ||||
|       console.log(chalk.green('token:', userToken.token)); | ||||
|       await opts?.saveToken(userToken.token); | ||||
|       console.log(chalk.green('网页登录成功')); | ||||
|       return; | ||||
|     } catch (error) { | ||||
|       console.log(chalk.red('登录失败'), error); | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
|   console.log(chalk.red('登录失败'), res); | ||||
| }; | ||||
|  | ||||
| export const loginInCommand = async (saveToken: any) => { | ||||
|   const { url, token, tokenSecret } = await loginWithWeb(); | ||||
|   await pollLoginStatus(token, { tokenSecret, saveToken }); | ||||
|   return url; | ||||
| export const loginInCommand = async () => { | ||||
|   const baseURL = getBaseURL(); | ||||
|   const res = queryLogin.loginWithWeb(baseURL, { MD5, jsonwebtoken }); | ||||
|   console.log(chalk.blue(res.url)); | ||||
|   await pollLoginStatus(res.token, { tokenSecret: res.tokenSecret }); | ||||
|   return res.url; | ||||
| }; | ||||
|  | ||||
| // loginInCommand(); | ||||
|   | ||||
| @@ -1,7 +1,9 @@ | ||||
| import { Query } from '@kevisual/query/query'; | ||||
| import { getConfig } from './get-config.ts'; | ||||
| import { QueryLoginNode, storage } from '@kevisual/query-login/node'; | ||||
| const config = getConfig(); | ||||
| export const baseURL = config?.baseURL || 'https://envision.xiongxiao.me'; | ||||
| export const baseURL = config?.baseURL || 'https://kevisual.cn'; | ||||
| export { storage }; | ||||
| export const getBaseURL = () => { | ||||
|   if (typeof config?.dev === 'undefined') { | ||||
|     return baseURL; | ||||
| @@ -23,10 +25,29 @@ export const query = new Query({ | ||||
|  | ||||
| query.beforeRequest = async (config) => { | ||||
|   if (config.headers) { | ||||
|     const token = await getConfig()?.token; | ||||
|     const token = await storage.getItem('token'); | ||||
|     if (token) { | ||||
|       config.headers['Authorization'] = 'Bearer ' + token; | ||||
|     } | ||||
|   } | ||||
|   return config; | ||||
| }; | ||||
| query.afterResponse = async (response, ctx) => { | ||||
|   if (response.code === 401) { | ||||
|     if (query.stop) { | ||||
|       return { | ||||
|         code: 500, | ||||
|         message: '登录已过期', | ||||
|       }; | ||||
|     } | ||||
|     query.stop = true; | ||||
|     const res = await queryLogin.afterCheck401ToRefreshToken(response, ctx); | ||||
|     query.stop = false; | ||||
|     return res; | ||||
|   } | ||||
|   return response as any; | ||||
| }; | ||||
| export const queryLogin = new QueryLoginNode({ | ||||
|   query: query as any, | ||||
|   onLoad: async () => {}, | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user