重构login

This commit is contained in:
xion 2025-03-21 20:41:12 +08:00
parent 4f12ed332c
commit f09a97d74a
2 changed files with 70 additions and 20 deletions

View File

@ -87,7 +87,7 @@ export class User extends Model {
static async getUserByToken(token: string) { static async getUserByToken(token: string) {
const oauthUser = await oauth.verifyToken(token); const oauthUser = await oauth.verifyToken(token);
if (!oauthUser) { if (!oauthUser) {
throw new CustomError('Token is invalid'); throw new CustomError('Token is invalid. get UserByToken');
} }
const userId = oauthUser?.uid || oauthUser.id; const userId = oauthUser?.uid || oauthUser.id;
const user = await User.findByPk(userId); const user = await User.findByPk(userId);

View File

@ -52,6 +52,7 @@ export type OauthUser = {
}; };
export type UserExpand = { export type UserExpand = {
createTime?: number; createTime?: number;
accessToken?: string;
refreshToken?: string; refreshToken?: string;
[key: string]: any; [key: string]: any;
} & StoreSetOpts; } & StoreSetOpts;
@ -66,7 +67,8 @@ interface Store<T> {
getObject: (key: string) => Promise<T>; getObject: (key: string) => Promise<T>;
setObject: (key: string, value: T, opts?: StoreSetOpts) => Promise<void>; setObject: (key: string, value: T, opts?: StoreSetOpts) => Promise<void>;
expire: (key: string, ttl?: number) => Promise<void>; expire: (key: string, ttl?: number) => Promise<void>;
delObject: (key: string, value?: T) => Promise<void>; delObject: (value?: T) => Promise<void>;
keys: (key?: string) => Promise<string[]>;
setToken: (value: { accessToken: string; refreshToken: string; value?: T }, opts?: StoreSetOpts) => Promise<void>; setToken: (value: { accessToken: string; refreshToken: string; value?: T }, opts?: StoreSetOpts) => Promise<void>;
} }
export class RedisTokenStore implements Store<OauthUser> { export class RedisTokenStore implements Store<OauthUser> {
@ -82,27 +84,49 @@ export class RedisTokenStore implements Store<OauthUser> {
async get(key: string) { async get(key: string) {
return await this.redis.get(this.prefix + key); return await this.redis.get(this.prefix + key);
} }
async expire(key: string, ttl?: number) {
await this.redis.expire(this.prefix + key, ttl);
}
async keys(key?: string) {
return await this.redis.keys(this.prefix + key);
}
async getObject(key: string) { async getObject(key: string) {
try { try {
const value = await this.get(key); const value = await this.get(key);
if (!value) { if (!value) {
console.log('getObject key not found', key);
return null; return null;
} }
console.log('getObject key found', key, value);
return JSON.parse(value); return JSON.parse(value);
} catch (error) { } catch (error) {
console.log('get key parse error', error);
return null; return null;
} }
} }
async del(key: string) {
const number = await this.redis.del(this.prefix + key);
console.log('del', key, number);
}
async setObject(key: string, value: OauthUser, opts?: StoreSetOpts) { async setObject(key: string, value: OauthUser, opts?: StoreSetOpts) {
await this.set(key, JSON.stringify(value), opts?.expire); await this.set(key, JSON.stringify(value), opts?.expire);
} }
async expire(key: string, ttl?: number) { async delObject(value?: OauthUser) {
await this.redis.expire(this.prefix + key, ttl); const refreshToken = value?.oauthExpand?.refreshToken;
} const accessToken = value?.oauthExpand?.accessToken;
async delObject(key: string, value?: OauthUser) { // 清理userPerfix
await this.redis.del(this.prefix + key); let userPrefix = 'user:' + value?.id;
if (value) { if (value?.orgId) {
// await this.redis.del(this.prefix + value.refreshToken); userPrefix = 'org:' + value?.orgId + ':user:' + value?.id;
}
console.log('delObject userPrefix', userPrefix, refreshToken, accessToken);
if (refreshToken) {
await this.del(refreshToken);
await this.del(userPrefix + ':refreshToken:' + refreshToken);
}
if (accessToken) {
await this.del(accessToken);
await this.del(userPrefix + ':token:' + accessToken);
} }
} }
async setToken(data: { accessToken: string; refreshToken: string; value?: OauthUser }, opts?: StoreSetOpts) { async setToken(data: { accessToken: string; refreshToken: string; value?: OauthUser }, opts?: StoreSetOpts) {
@ -171,6 +195,7 @@ export class OAuth<T extends OauthUser> {
user.oauthExpand = { user.oauthExpand = {
...user.oauthExpand, ...user.oauthExpand,
...expandOpts, ...expandOpts,
accessToken,
createTime: new Date().getTime(), // createTime: new Date().getTime(), //
}; };
if (expandOpts?.hasRefreshToken) { if (expandOpts?.hasRefreshToken) {
@ -187,7 +212,11 @@ export class OAuth<T extends OauthUser> {
* @returns * @returns
*/ */
async verifyToken(token: string) { async verifyToken(token: string) {
return await this.store.getObject(token); console.log('verifyToken get token', token);
const res = await this.store.getObject(token);
console.log('verifyToken get res', res);
console.log('resetToken token', await this.store.keys());
return res;
} }
/** /**
* token * token
@ -200,12 +229,17 @@ export class OAuth<T extends OauthUser> {
// 过期 // 过期
throw new Error('Refresh token not found'); throw new Error('Refresh token not found');
} }
const token = await this.generateToken(user, {
...user.oauthExpand,
hasRefreshToken: true,
});
// 删除旧的token // 删除旧的token
await this.store.delObject(refreshToken, user); await this.store.delObject({ ...user });
const token = await this.generateToken(
{ ...user },
{
...user.oauthExpand,
hasRefreshToken: true,
},
);
console.log('resetToken token', await this.store.keys());
return token; return token;
} }
/** /**
@ -223,16 +257,32 @@ export class OAuth<T extends OauthUser> {
user.oauthExpand = user.oauthExpand || {}; user.oauthExpand = user.oauthExpand || {};
const refreshToken = user.oauthExpand.refreshToken; const refreshToken = user.oauthExpand.refreshToken;
if (refreshToken) { if (refreshToken) {
await this.store.delObject(refreshToken, user); await this.store.delObject(user);
} }
user.oauthExpand = { user.oauthExpand = {
...user.oauthExpand, ...user.oauthExpand,
...expand, ...expand,
}; };
const token = await this.generateToken(user, { const token = await this.generateToken(
...user.oauthExpand, { ...user },
hasRefreshToken: true, {
}); ...user.oauthExpand,
hasRefreshToken: true,
},
);
return token; return token;
} }
/**
* token
* @param token
*/
async delToken(token: string) {
const user = await this.store.getObject(token);
if (!user) {
// 过期
throw new Error('token not found');
}
this.store.delObject(user);
}
} }