优化 token 处理逻辑,统一 createCookie 调用格式,返回 token 过期时间
This commit is contained in:
@@ -62,7 +62,13 @@ export class User extends Model {
|
||||
oauthUser.orgId = id;
|
||||
}
|
||||
const token = await oauth.generateToken(oauthUser, { type: loginType, hasRefreshToken: true, ...expand });
|
||||
return { accessToken: token.accessToken, refreshToken: token.refreshToken, token: token.accessToken };
|
||||
return {
|
||||
accessToken: token.accessToken,
|
||||
refreshToken: token.refreshToken,
|
||||
token: token.accessToken,
|
||||
accessTokenExpiresAt: token.accessTokenExpiresAt,
|
||||
refreshTokenExpiresAt: token.refreshTokenExpiresAt,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 验证token
|
||||
|
||||
@@ -70,9 +70,16 @@ interface Store<T> {
|
||||
expire: (key: string, ttl?: number) => 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<TokenData>;
|
||||
delKeys: (keys: string[]) => Promise<number>;
|
||||
}
|
||||
|
||||
type TokenData = {
|
||||
accessToken: string;
|
||||
accessTokenExpiresAt: number;
|
||||
refreshToken?: string;
|
||||
refreshTokenExpiresAt?: number;
|
||||
}
|
||||
export class RedisTokenStore implements Store<OauthUser> {
|
||||
redis: Redis;
|
||||
private prefix: string = 'oauth:';
|
||||
@@ -131,7 +138,7 @@ export class RedisTokenStore implements Store<OauthUser> {
|
||||
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): Promise<TokenData> {
|
||||
const { accessToken, refreshToken, value } = data;
|
||||
let userPrefix = 'user:' + value?.id;
|
||||
if (value?.orgId) {
|
||||
@@ -163,14 +170,20 @@ export class RedisTokenStore implements Store<OauthUser> {
|
||||
|
||||
await this.set(accessToken, JSON.stringify(value), expire);
|
||||
await this.set(userPrefix + ':token:' + accessToken, accessToken, expire);
|
||||
let refreshTokenExpiresAt = Math.min(expire * 7, 60 * 60 * 24 * 30, 60 * 60 * 24 * 365); // 最大为一年
|
||||
if (refreshToken) {
|
||||
let refreshTokenExpire = Math.min(expire * 7, 60 * 60 * 24 * 30, 60 * 60 * 24 * 365); // 最大为一年
|
||||
// 小于7天, 则设置为7天
|
||||
if (refreshTokenExpire < 60 * 60 * 24 * 7) {
|
||||
refreshTokenExpire = 60 * 60 * 24 * 7;
|
||||
if (refreshTokenExpiresAt < 60 * 60 * 24 * 7) {
|
||||
refreshTokenExpiresAt = 60 * 60 * 24 * 7;
|
||||
}
|
||||
await this.set(refreshToken, JSON.stringify(value), refreshTokenExpire);
|
||||
await this.set(userPrefix + ':refreshToken:' + refreshToken, refreshToken, refreshTokenExpire);
|
||||
await this.set(refreshToken, JSON.stringify(value), refreshTokenExpiresAt);
|
||||
await this.set(userPrefix + ':refreshToken:' + refreshToken, refreshToken, refreshTokenExpiresAt);
|
||||
}
|
||||
return {
|
||||
accessToken,
|
||||
accessTokenExpiresAt: expire,
|
||||
refreshToken,
|
||||
refreshTokenExpiresAt,
|
||||
}
|
||||
}
|
||||
async delKeys(keys: string[]) {
|
||||
@@ -206,10 +219,7 @@ export class OAuth<T extends OauthUser> {
|
||||
async generateToken(
|
||||
user: T,
|
||||
expandOpts?: StoreSetOpts,
|
||||
): Promise<{
|
||||
accessToken: string;
|
||||
refreshToken?: string;
|
||||
}> {
|
||||
): Promise<TokenData> {
|
||||
// 拥有refreshToken 为 true 时,accessToken 为 st_ 开头,refreshToken 为 rk_开头
|
||||
// 意思是secretToken 和 secretKey的缩写
|
||||
const accessToken = expandOpts?.hasRefreshToken ? 'st_' + randomId32() : 'sk_' + randomId64();
|
||||
@@ -227,9 +237,9 @@ export class OAuth<T extends OauthUser> {
|
||||
user.oauthExpand.refreshToken = refreshToken;
|
||||
}
|
||||
}
|
||||
await this.store.setToken({ accessToken, refreshToken, value: user }, expandOpts);
|
||||
const tokenData = await this.store.setToken({ accessToken, refreshToken, value: user }, expandOpts);
|
||||
|
||||
return { accessToken, refreshToken };
|
||||
return tokenData;
|
||||
}
|
||||
async saveSecretKey(oauthUser: T, secretKey: string, opts?: StoreSetOpts) {
|
||||
// 生成一个secretKey
|
||||
|
||||
@@ -59,10 +59,7 @@ app
|
||||
}
|
||||
}
|
||||
await config.update({
|
||||
data: {
|
||||
...config.data,
|
||||
...data,
|
||||
},
|
||||
data: data,
|
||||
...rest,
|
||||
});
|
||||
if (config.data?.permission?.share === 'public') {
|
||||
@@ -80,7 +77,7 @@ app
|
||||
});
|
||||
if (config) {
|
||||
await config.update({
|
||||
data: { ...config.data, ...data },
|
||||
data: data,
|
||||
...rest,
|
||||
});
|
||||
ctx.body = config;
|
||||
@@ -177,7 +174,7 @@ app
|
||||
const search: any = id ? { id } : { key };
|
||||
const config = await ConfigModel.findOne({
|
||||
where: {
|
||||
...search
|
||||
...search
|
||||
},
|
||||
});
|
||||
if (config && config.uid === tuid) {
|
||||
|
||||
@@ -153,7 +153,9 @@ app
|
||||
browser: someInfo['user-agent'],
|
||||
host: someInfo.host,
|
||||
});
|
||||
createCookie(token, ctx);
|
||||
createCookie({
|
||||
token: token.accessToken
|
||||
}, ctx);
|
||||
ctx.body = token;
|
||||
})
|
||||
.addTo(app);
|
||||
@@ -259,7 +261,10 @@ app
|
||||
const refreshToken = accessUser.oauthExpand?.refreshToken;
|
||||
if (refreshToken) {
|
||||
const result = await User.oauth.refreshToken(refreshToken);
|
||||
createCookie(result, ctx);
|
||||
createCookie({
|
||||
token: result.accessToken
|
||||
}, ctx);
|
||||
|
||||
ctx.body = result;
|
||||
return;
|
||||
} else if (accessUser) {
|
||||
@@ -268,7 +273,9 @@ app
|
||||
...accessUser.oauthExpand,
|
||||
hasRefreshToken: true,
|
||||
});
|
||||
createCookie(result, ctx);
|
||||
createCookie({
|
||||
token: result.accessToken
|
||||
}, ctx);
|
||||
ctx.body = result;
|
||||
return;
|
||||
}
|
||||
@@ -323,13 +330,17 @@ app
|
||||
if (orgsList.includes(username)) {
|
||||
if (tokenUsername === username) {
|
||||
const result = await User.oauth.resetToken(token);
|
||||
createCookie(result, ctx);
|
||||
createCookie({
|
||||
token: result.accessToken,
|
||||
}, ctx);
|
||||
await User.oauth.delToken(token);
|
||||
ctx.body = result;
|
||||
} else {
|
||||
const user = await User.findOne({ where: { username } });
|
||||
const result = await user.createToken(userId, 'default');
|
||||
createCookie(result, ctx);
|
||||
createCookie({
|
||||
token: result.accessToken,
|
||||
}, ctx);
|
||||
ctx.body = result;
|
||||
}
|
||||
} else {
|
||||
@@ -352,7 +363,9 @@ app
|
||||
const result = await User.oauth.refreshToken(refreshToken);
|
||||
if (result) {
|
||||
console.log('refreshToken result', result);
|
||||
createCookie(result, ctx);
|
||||
createCookie({
|
||||
token: result.accessToken,
|
||||
}, ctx);
|
||||
ctx.body = result;
|
||||
} else {
|
||||
ctx.throw(500, 'Refresh Token Failed, please login again');
|
||||
|
||||
@@ -109,7 +109,9 @@ app
|
||||
const token = JSON.parse(data);
|
||||
if (token.accessToken) {
|
||||
ctx.body = token;
|
||||
createCookie(token, ctx);
|
||||
createCookie({
|
||||
token: token.accessToken,
|
||||
}, ctx);
|
||||
} else {
|
||||
ctx.throw(500, 'Checked error Failed, login failed, please login again');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user