北斗启航科技教育平台登录系统
This commit is contained in:
333
app/extend/oauth.js
Normal file
333
app/extend/oauth.js
Normal 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;
|
||||
};
|
||||
Reference in New Issue
Block a user