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