hn-hlw-service/utils/jwt-utils.js

151 lines
3.6 KiB
JavaScript
Raw Normal View History

2026-07-27 11:28:33 +08:00
const jwt = require('jsonwebtoken');
const logger = require('./logger');
/**
* JWT 工具类
* 提供 token 生成验证刷新等功能
*/
class JWTUtils {
constructor() {
this.secret = process.env.JWT_SECRET || 'your-secret-key';
this.refreshSecret = process.env.JWT_REFRESH_SECRET || 'your-refresh-secret-key';
// Access token 过期时间(默认 2 小时)
this.accessTokenExpiry = process.env.JWT_ACCESS_EXPIRY || '24h';
// Refresh token 过期时间(默认 7 天)
this.refreshTokenExpiry = process.env.JWT_REFRESH_EXPIRY || '7d';
}
/**
* 生成访问令牌
* @param {Object} payload - 用户信息载荷
* @returns {String} access token
*/
generateAccessToken(payload) {
const data = {
userId: payload.userId,
username: payload.username,
corpId: payload.corpId,
role: payload.role,
type: 'access',
platform: payload.platform || '',
};
return jwt.sign(data, this.secret, {
expiresIn: this.accessTokenExpiry,
issuer: 'zyt-hlw-service'
});
}
/**
* 生成刷新令牌
* @param {Object} payload - 用户信息载荷
* @returns {String} refresh token
*/
generateRefreshToken(payload) {
const data = {
userId: payload.userId,
username: payload.username,
type: 'refresh'
};
return jwt.sign(data, this.refreshSecret, {
expiresIn: this.refreshTokenExpiry,
issuer: 'zyt-hlw-service'
});
}
/**
* 生成访问令牌和刷新令牌
* @param {Object} payload - 用户信息载荷
* @returns {Object} { accessToken, refreshToken }
*/
generateTokens(payload) {
const accessToken = this.generateAccessToken(payload);
const refreshToken = this.generateRefreshToken(payload);
return {
accessToken,
refreshToken,
expiresIn: this.parseExpiry(this.accessTokenExpiry)
};
}
/**
* 验证访问令牌
* @param {String} token - 访问令牌
* @returns {Object} 解码后的载荷
*/
verifyAccessToken(token) {
return jwt.verify(token, this.secret);
}
/**
* 验证刷新令牌
* @param {String} token - 刷新令牌
* @returns {Object} 解码后的载荷
*/
verifyRefreshToken(token) {
return jwt.verify(token, this.refreshSecret);
}
/**
* 使用刷新令牌生成新的访问令牌
* @param {String} refreshToken - 刷新令牌
* @returns {Object} { accessToken, expiresIn }
*/
refreshAccessToken(refreshToken) {
const decoded = this.verifyRefreshToken(refreshToken);
if (decoded.type !== 'refresh') {
throw new Error('Invalid token type');
}
// 生成新的访问令牌
const accessToken = this.generateAccessToken({
userId: decoded.userId,
username: decoded.username
});
return {
accessToken,
expiresIn: this.parseExpiry(this.accessTokenExpiry)
};
}
/**
* 解析过期时间字符串为秒数
* @param {String} expiry - 过期时间字符串 '2h', '7d'
* @returns {Number} 秒数
*/
parseExpiry(expiry) {
const match = expiry.match(/^(\d+)([smhd])$/);
if (!match) return 7200; // 默认 2 小时
const value = parseInt(match[1]);
const unit = match[2];
const multipliers = {
's': 1,
'm': 60,
'h': 3600,
'd': 86400
};
return value * (multipliers[unit] || 3600);
}
/**
* 解码 token不验证签名
* @param {String} token
* @returns {Object} 解码后的载荷
*/
decode(token) {
return jwt.decode(token);
}
}
// 导出单例
module.exports = new JWTUtils();