feat: 添加JWKS token支持,更新用户和OAuth相关逻辑
This commit is contained in:
@@ -38,6 +38,11 @@ export const redis = useContextKey<Redis>('redis');
|
||||
|
||||
type TokenOptions = {
|
||||
expire?: number; // 过期时间,单位秒
|
||||
ip?: string; // 用户ID,默认为当前用户ID
|
||||
browser?: string; // 浏览器信息
|
||||
host?: string; // 主机信息
|
||||
wx?: any;
|
||||
loginWith?: string; // 登录方式,如 'cli', 'web', 'plugin' 等
|
||||
}
|
||||
/**
|
||||
* 用户模型,使用 Drizzle ORM
|
||||
@@ -85,21 +90,25 @@ export class User {
|
||||
oauthUser.orgId = id;
|
||||
}
|
||||
if (loginType === 'jwks') {
|
||||
const expiresIn = opts?.expire ?? 2 * 3600; // 2 hours
|
||||
const accessToken = await jwksManager.sign({
|
||||
sub: 'user:' + this.id,
|
||||
name: this.username,
|
||||
exp: Math.floor(Date.now() / 1000) + expiresIn,
|
||||
});
|
||||
const expiresIn = opts?.expire ?? 2 * 3600; // 2 hours
|
||||
await oauth.setJwksToken(accessToken, { id: this.id, expire: expiresIn });
|
||||
return {
|
||||
type: 'jwks',
|
||||
accessToken: accessToken,
|
||||
refreshToken: null,
|
||||
refreshToken: accessToken,
|
||||
token: accessToken,
|
||||
refreshTokenExpiresIn: null,
|
||||
refreshTokenExpiresIn: expiresIn,
|
||||
accessTokenExpiresIn: expiresIn
|
||||
};
|
||||
}
|
||||
const token = await oauth.generateToken(oauthUser, { type: loginType, hasRefreshToken: true, ...opts });
|
||||
return {
|
||||
type: 'default',
|
||||
accessToken: token.accessToken,
|
||||
refreshToken: token.refreshToken,
|
||||
token: token.accessToken,
|
||||
@@ -121,8 +130,73 @@ export class User {
|
||||
* @returns
|
||||
*/
|
||||
static async refreshToken(refreshToken: string) {
|
||||
if (refreshToken?.includes?.('.')) {
|
||||
// 可能是 jwks token
|
||||
const jwksToken = await oauth.getJwksToken(refreshToken);
|
||||
if (!jwksToken) {
|
||||
throw new CustomError('Invalid refresh token');
|
||||
}
|
||||
const decoded = await jwksManager.decode(refreshToken);
|
||||
const sub = decoded.sub;
|
||||
const username = decoded.name;
|
||||
const expiresIn = 2 * 3600; // 2 hours
|
||||
const newToken = await jwksManager.sign({
|
||||
sub,
|
||||
name: username,
|
||||
exp: Math.floor(Date.now() / 1000) + expiresIn,
|
||||
});
|
||||
oauth.setJwksToken(newToken, { id: sub.replace('user:', ''), expire: expiresIn });
|
||||
return {
|
||||
type: 'jwks',
|
||||
accessToken: newToken,
|
||||
refreshToken: newToken,
|
||||
token: newToken,
|
||||
refreshTokenExpiresIn: expiresIn,
|
||||
accessTokenExpiresIn: expiresIn,
|
||||
}
|
||||
}
|
||||
const token = await oauth.refreshToken(refreshToken);
|
||||
return { accessToken: token.accessToken, refreshToken: token.refreshToken, token: token.accessToken };
|
||||
return {
|
||||
type: 'default',
|
||||
accessToken: token.accessToken,
|
||||
refreshToken: token.refreshToken,
|
||||
token: token.accessToken,
|
||||
accessTokenExpiresIn: token.accessTokenExpiresIn,
|
||||
refreshTokenExpiresIn: token.refreshTokenExpiresIn,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 重置token,立即过期token
|
||||
* @param token
|
||||
* @returns
|
||||
*/
|
||||
static async resetToken(refreshToken: string, expand?: Record<string, any>) {
|
||||
if (refreshToken?.includes?.('.')) {
|
||||
// 可能是 jwks token
|
||||
const jwksToken = await oauth.getJwksToken(refreshToken);
|
||||
if (!jwksToken) {
|
||||
throw new CustomError('Invalid refresh token');
|
||||
}
|
||||
const decoded = await jwksManager.decode(refreshToken);
|
||||
const sub = decoded.sub;
|
||||
const username = decoded.name;
|
||||
const expiresIn = 2 * 3600; // 2 hours
|
||||
const newToken = await jwksManager.sign({
|
||||
sub,
|
||||
name: username,
|
||||
exp: Math.floor(Date.now() / 1000) + expiresIn,
|
||||
});
|
||||
oauth.setJwksToken(newToken, { id: sub.replace('user:', ''), expire: expiresIn });
|
||||
return {
|
||||
type: 'jwks',
|
||||
accessToken: newToken,
|
||||
refreshToken: newToken,
|
||||
token: newToken,
|
||||
refreshTokenExpiresIn: expiresIn,
|
||||
accessTokenExpiresIn: expiresIn,
|
||||
};
|
||||
}
|
||||
return await oauth.resetToken(refreshToken, expand);
|
||||
}
|
||||
static async getOauthUser(token: string) {
|
||||
return await UserSecret.verifyToken(token);
|
||||
|
||||
Reference in New Issue
Block a user