北斗启航科技教育平台登录系统

This commit is contained in:
2026-03-27 17:50:18 +08:00
commit bdc25653a4
215 changed files with 5299 additions and 0 deletions

333
app/extend/oauth.js Normal file
View File

@@ -0,0 +1,333 @@
'use strict';
// const sha256 = require("crypto-js/sha256");
module.exports = () => {
class Model {
constructor(ctx) {
this.ctx = ctx;
this.fileName = "oauth";
this.redisType = {
"B": "db0",
"C": "db1",
"M": "db2",
"T": "db5",
"E": "db6",
"A": "db7"
};
this.modelType = {
"B": this.ctx.model.BSide,
"C": this.ctx.model2.CSide,
"M": this.ctx.model3.Insiders,
"T": this.ctx.model4.Account,
"E": this.ctx.model5.Examinee,
"A": this.ctx.model5.Manager,
};
this.redisAccessTokenEX = {
"B": 1000,
"C": 1000,
"M": 1000,
"T": 1000,
"E": 3000,
"A": 1000
};
this.redisRefreshTokenEX = {
"B": 1000,
"C": 1000,
"M": 1000,
"T": 1000,
"E": 360000,
"A": 1000
};
}
async getClient(clientId) {
// let clientSecret = this.ctx.request.body.client_secret;
try {
// 1. 从数据库中查询客户端信息
// if(clientId == "insiders-manager" && clientSecret == "insiders-manager") {
let checkFixedClient = false;
this.ctx.app.config.fixedClient.forEach(element => {
if (clientId == element) checkFixedClient = true;
});
if (checkFixedClient) {
return {
id: clientId,
redirectUris: 'http://127.0.0.1:'+this.ctx.app.server.address().port+'/getToken/',
grants: ['authorization_code'],
type: clientId,
};
} else {
const client = await this.ctx.model3.Business.findOne({ where: { client_id: clientId } });
if (!client) return false;
// 2. 校验客户端密钥
// if (clientSecret && (clientSecret !== client.client_secret)) {
// return false;
// }
// 3. 返回数据
return {
id: client.client_id,
redirectUris: 'http://127.0.0.1:'+this.ctx.app.server.address().port+'/getToken/',
grants: ['authorization_code'],
type: client.type,
};
}
} catch (error) {
const blockName = this.fileName + "--" + "getClient";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async grantTypeAllowed (clientId, grantType) {
try {
const client = await this.ctx.model.Oauth2.findOne({ where: { clientId: clientId } });
if(clientId == client.clientId && grantType == client.grants.split(',')){
return true;
}else{
return false;
}
} catch (error) {
const blockName = this.fileName + "--" + "grantTypeAllowed";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async getUser(username, password) {
try {
// 返回用户信息
return {
uid: username,
};
} catch (error) {
const blockName = this.fileName + "--" + "getUser";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async getUserFromClient (clientId) {
try {
return {
uid:clientId.id
};
} catch (error) {
const blockName = this.fileName + "--" + "getUserFromClient";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
};
async saveToken(token, client, user) {
try {
const rdmtoken = {
accessToken: token.accessToken,
refreshToken: token.refreshToken,
clientId: client.id,
};
const lastCode = user.uid[user.uid.length-1];
const redisDbType = this.redisType[lastCode];
const redisAccessTokenEX = this.redisAccessTokenEX[lastCode];
const redisRefreshTokenEX = this.redisRefreshTokenEX[lastCode];
let reex = ((new Date(token.refreshTokenExpiresAt).getTime() - new Date().getTime()) / redisRefreshTokenEX).toFixed(0);
const usertoken = await this.ctx.app.redis.get(redisDbType).get(user.uid);
if(usertoken){
await this.ctx.app.redis.get(redisDbType).del(JSON.parse(usertoken).accessToken);
let remainder = await this.ctx.app.redis.get(redisDbType).ttl(user.uid);
reex = remainder;
await this.ctx.app.redis.get(redisDbType).del(JSON.parse(usertoken).refreshToken);
}
await this.ctx.app.redis.get(redisDbType).set(user.uid, JSON.stringify(rdmtoken), 'EX', reex);
// 1.保存访问令牌
const rdmaccess = {
token: token.accessToken,
expiresAt: token.accessTokenExpiresAt,
scope: token.scope || '',
clientId: client.id,
clientType: client.type,
uid: user.uid,
};
let acex = ((new Date(token.accessTokenExpiresAt).getTime() - new Date().getTime()) / redisAccessTokenEX).toFixed(0);
await this.ctx.app.redis.get(redisDbType).set(token.accessToken, JSON.stringify(rdmaccess), 'EX', acex);
// 2.保存刷新令牌
if(token.refreshToken){
const rdmrefresh = {
token: token.refreshToken,
expiresAt: token.refreshTokenExpiresAt,
scope: token.scope || '',
clientId: client.id,
clientType: client.type,
uid: user.uid,
};
await this.ctx.app.redis.get(redisDbType).set(token.refreshToken, JSON.stringify(rdmrefresh), 'EX', reex);
}
// 3.返回保存的令牌信息
return {
accessToken: { uid: user.uid, token:token.accessToken },
accessTokenExpiresAt: token.accessTokenExpiresAt,
refreshToken: token.refreshToken ? token.refreshToken : '',
refreshTokenExpiresAt: token.refreshTokenExpiresAt ? token.refreshTokenExpiresAt : '',
scope: token.scope || '',
client: { id: client.id, type: client.type },
user: { uid: user.uid },
};
} catch (error) {
const blockName = this.fileName + "--" + "saveToken";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async getAccessToken(bearerToken) {
try {
// 1. 查询数据库,获取访问密钥信息
// 2. 查询数据库,获取客户端信息
// 3. 查询数据库,获取用户信息
let { access_token, uid } = JSON.parse(bearerToken);
const lastCode = uid[uid.length-1];
const redisDbType = this.redisType[lastCode];
const token = await this.ctx.app.redis.get(redisDbType).get(access_token);
if (token == null) {
const data = await this.ctx.app.redis.get(redisDbType).get(uid);
const refreshToken = await this.ctx.app.redis.get(redisDbType).get(JSON.parse(data).refreshToken);
if (refreshToken == null) await this.ctx.app.redis.get(redisDbType).del(uid);
};
// 4. 返回数据
let accessToken = {
accessTokenExpiresAt: new Date(JSON.parse(token).expiresAt),
user: { uid: JSON.parse(token).uid },
client_type: JSON.parse(token).clientType,
}
return accessToken;
} catch (error) {
const blockName = this.fileName + "--" + "getAccessToken";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async revokeToken(token) {
try {
// 查询数据库并删除刷新令牌
const revokeValue = await this.ctx.app.redis.del(token.refreshToken);
if(revokeValue){
return true;
}else{
return false;
}
} catch (error) {
const blockName = this.fileName + "--" + "revokeToken";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async saveAuthorizationCode(code, client, user) {
try {
// 1. 保存授权码信息到数据库
const rdmcode = {
code: code.authorizationCode,
expiresAt: code.expiresAt,
redirectUri: code.redirectUri,
scope: code.scope || '',
clientId: client.id,
clientType: client.type,
uid: user.uid
}
let ex = ((new Date(code.expiresAt).getTime() - new Date().getTime()) / 1000).toFixed(0);
await this.ctx.app.redis.get('db3').set(code.authorizationCode, JSON.stringify(rdmcode), 'EX', ex);
// 2. 返回数据
return {
authorizationCode: code.authorizationCode,
expiresAt: code.expiresAt,
redirectUri: code.redirectUri,
scope: code.scope || '',
client: { id: client.id },
user: { uid: user.uid },
};
} catch (error) {
const blockName = this.fileName + "--" + "saveAuthorizationCode";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async getAuthorizationCode(authorizationCode) {
try {
// 1. 从数据库中查询授权码信息
const { code, type } = JSON.parse(authorizationCode);
const lastCode = type[type.length - 1];
const redisDbType = this.redisType[lastCode];
let rdmcode;
if(type == 'code') {
rdmcode = await this.ctx.app.redis.get('db3').get(code);
} else {
rdmcode = await this.ctx.app.redis.get(redisDbType).get(code);
}
if (!rdmcode) return false;
// 2. 从数据库中查询客户端信息、用户信息
const cloneRdmcode = JSON.parse(rdmcode);
const cloneLastCode = cloneRdmcode.uid[cloneRdmcode.uid.length-1];
const modelDbType = this.modelType[cloneLastCode];
const user = await modelDbType.findOne({ where: { uid: cloneRdmcode.uid } });
if (!user) return false;
// 3. 返回数据
return {
code: authorizationCode,
expiresAt: new Date(cloneRdmcode.expiresAt),
redirectUri: cloneRdmcode.redirectUri,
scope: cloneRdmcode.scope,
client: { id: cloneRdmcode.clientId },
user: { uid: cloneRdmcode.uid },
};
} catch (error) {
const blockName = this.fileName + "--" + "getAuthorizationCode";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async revokeAuthorizationCode(authorizationCode) {
try {
// 从数据库中查询该授权码并删除
const { code, type } = JSON.parse(authorizationCode.code);
const lastCode = type[type.length - 1];
const redisDbType = this.redisType[lastCode];
let revokeValue;
if(type == 'code') {
revokeValue = await this.ctx.app.redis.get('db3').del(code);
} else {
revokeValue = await this.ctx.app.redis.get(redisDbType).del(code);
}
if(revokeValue){
return true;
}else{
return false;
}
} catch (error) {
const blockName = this.fileName + "--" + "revokeAuthorizationCode";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
async getRefreshToken(refreshToken) {
try {
// 1. 查询数据库获取刷新令牌
const rdmrefresh = await this.ctx.app.redis.get(refreshToken);
if (!rdmrefresh) return false;
// 2. 返回数据
return {
refreshToken: JSON.parse(rdmrefresh).token,
refreshTokenExpiresAt: new Date(JSON.parse(rdmrefresh).expiresAt),
scope: JSON.parse(rdmrefresh).scope,
client: { id: JSON.parse(rdmrefresh).clientId },
user: { uid: JSON.parse(rdmrefresh).uid },
};
} catch (error) {
const blockName = this.fileName + "--" + "getRefreshToken";
this.ctx.app.middleware.log('../../oauthLog', blockName + ">>>>" + error);
return false;
}
}
}
return Model;
};