aozhiwei 9df5e6ef19 1
2024-06-07 14:31:58 +08:00

131 lines
3.1 KiB
JavaScript

const app = require('j7/app');
const utils = require('j7/utils');
const base64url = require('base64url');
const jwksClient = require('jwks-rsa');
const jwt = require('jsonwebtoken');
const LOCK_KEY = 'getJwtLock:';
const jwksKeyHash = {};
async function refreshKey() {
while (true) {
const keyList = [];
Object.keys(jwksKeyHash).forEach((key) => {
const val = jwksKeyHash[key];
if (utils.getUtcTime() - val['lastRefreshTime'] > 60 * 30) {
keyList.push(val);
}
});
utils.serial
(keyList,
async (val) => {
const err = await asyncForceGetKey(val['uri'], val['header']);
if (!err) {
}
});
await utils.sleep(1000 * 60 * 5);
}
}
async function asyncForceGetKey(jwksUri, header) {
return new Promise((resolve) => {
const client = jwksClient({
jwksUri: jwksUri
});
client.getSigningKey(header.kid, function(err, key) {
const signingKey = key.publicKey || key.rsaPublicKey;
if (!err) {
jwksKeyHash[jwksUri] = {
'key': key,
'uri': jwksUri,
'header': header,
'lastRefreshTime': utils.getUtcTime()
};
}
resolve(err);
});
});
}
async function asyncGetKey(jwksUri, header, cb) {
await app.lock(LOCK_KEY + jwksUri);
try {
if (jwksUri in jwksKeyHash) {
const c = jwksKeyHash[jwksUri];
console.log(c['key']);
cb(null, c['key']);
return;
}
const client = jwksClient({
jwksUri: jwksUri
});
client.getSigningKey(header.kid, function(err, key) {
try {
console.log(err, key);
const signingKey = key.publicKey || key.rsaPublicKey;
if (!err) {
jwksKeyHash[jwksUri] = {
'key': signingKey,
'uri': jwksUri,
'header': header,
'lastRefreshTime': utils.getUtcTime()
};
}
cb(null, signingKey);
} finally {
app.unLock(LOCK_KEY + jwksUri);
}
});
} finally {
app.unLock(LOCK_KEY + jwksUri);
}
}
function asyncVerify(jwksUri, data) {
return new Promise((resolve) => {
const ret = {
err: null,
decoded: null
};
jwt.verify
(data,
(header, cb) => {
asyncGetKey(jwksUri, header, cb);
},
(err, decoded) => {
console.log(err);
console.log(decoded);
ret.err = err;
ret.decoded = decoded;
resolve(ret);
});
});
}
async function verify(session) {
console.log('aaaaaaaaaaaaaa');
const postData = session.getBody();
const jwksUri = postData['jwksUri'];
//const arr = postData['data'].split('.');
//const header = base64url.decode(arr[0]);
//const payload = base64url.decode(arr[1]);
//const sign = base64url.decode(arr[2]);
const {err, decoded} = await asyncVerify(jwksUri, postData['data']);
console.log(err, decoded);
if (err != null) {
//console.log(postData);
session.rspErr(500, err);
return;
}
session.rspData({
'decoded': decoded
});
}
function init() {
refreshKey();
app.registerHandler('Jwt', 'verify', verify);
}
exports.init = init;