重构login
This commit is contained in:
parent
4f12ed332c
commit
f09a97d74a
@ -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);
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user