update
This commit is contained in:
parent
2e05f90851
commit
94837efdee
@ -36,5 +36,5 @@ controller.logout = () => async (ctx) => {
|
||||
}
|
||||
|
||||
controller.getInfo = () => async (ctx) => {
|
||||
ctx.resp(resp.Success, {})
|
||||
ctx.resp(resp.Success, ctx.token.info)
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ const joi = require('joi')
|
||||
const response = require('src/utils/response/index.js')
|
||||
const config = require('src/config/index.js')
|
||||
const { jwt } = require('src/utils/pkgs.js')
|
||||
const { copyObject, toNumber } = require('src/utils/index.js')
|
||||
const sso = require('src/utils/sso/index.js')
|
||||
const { copyObject } = require('src/utils/index.js')
|
||||
const { get: getCacheInstance } = require('src/utils/cache.js')
|
||||
|
||||
const { Success, InternalError, DataFormat, Forbidden, Unauthorized } = response.resp
|
||||
|
||||
@ -107,7 +109,7 @@ controller.validate = schema => {
|
||||
* @param {boolean=} allowExpired
|
||||
* @return {import('koa').Middleware}
|
||||
*/
|
||||
controller.authorization = allowExpired => {
|
||||
controller.authorization = () => {
|
||||
return async (ctx, next) => {
|
||||
ctx.token = {}
|
||||
/** @type {string} */
|
||||
@ -122,44 +124,40 @@ controller.authorization = allowExpired => {
|
||||
|
||||
[, ctx.token.origin] = strs
|
||||
|
||||
let decoded = {}
|
||||
let expired = false
|
||||
const decoded = {}
|
||||
|
||||
try {
|
||||
decoded = jwt.verify(strs[1], config.server.jwt_secret)
|
||||
// 可以考慮這邊做個cache 多久之內存取不會到keycloak驗證
|
||||
let userInfo = await sso.getUserInfo(ctx.token.origin)
|
||||
if (!userInfo) {
|
||||
// try refresh
|
||||
const cache = getCacheInstance()
|
||||
const refreshToken = cache.get(ctx.token.origin)
|
||||
if (!refreshToken) throw new Error('no cache data')
|
||||
const token = await sso.refreshToken(refreshToken)
|
||||
// set new cache
|
||||
cache.set(token.access_token, token.refresh_token, false)
|
||||
ctx.token.origin = token.access_token
|
||||
userInfo = await sso.getUserInfo(token.access_token)
|
||||
if (!userInfo) throw new Error('get user info fail')
|
||||
|
||||
await joi
|
||||
.object({
|
||||
user_id: joi.string().required()
|
||||
})
|
||||
.unknown()
|
||||
.validateAsync(decoded)
|
||||
ctx.set('x-new-token', ctx.token.origin)
|
||||
}
|
||||
|
||||
Object.assign(decoded, userInfo)
|
||||
} catch (err) {
|
||||
debug(`jwt token verify fail: ${util.inspect(err, false, null)}`)
|
||||
if (err instanceof jwt.TokenExpiredError) {
|
||||
decoded = jwt.decode(ctx.token.origin)
|
||||
expired = true
|
||||
} else {
|
||||
throw err
|
||||
}
|
||||
debug(`user info get fail ::: ${util.inspect(err, false, null)}`)
|
||||
ctx.err(Unauthorized)
|
||||
}
|
||||
|
||||
ctx.token.user_id = decoded.user_id
|
||||
ctx.token.sso = !!decoded.sso
|
||||
ctx.token.user_id = decoded.username
|
||||
ctx.token.sso = true
|
||||
|
||||
if (expired) ctx.err(Forbidden, response.codeMessage.CodeTokenExpired)
|
||||
ctx.token.info = decoded
|
||||
|
||||
ctx.verified = true
|
||||
} catch (err) {
|
||||
debug(`Token valid fail: ${util.inspect(err, false, null)}`)
|
||||
if (err instanceof response.APIError) {
|
||||
// 如果是過期的錯誤,判斷是否允許過期存取
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line
|
||||
if (err._object?.object?.code === response.codeMessage.CodeTokenExpired.code) {
|
||||
if (allowExpired) return next()
|
||||
}
|
||||
}
|
||||
throw err
|
||||
}
|
||||
|
||||
|
@ -3,9 +3,10 @@ const util = require('util')
|
||||
const url = require('url')
|
||||
const sso = require('src/utils/sso/index.js')
|
||||
const { get: getCacheInstance } = require('src/utils/cache.js')
|
||||
const { codeMessage, APIError } = require('src/utils/response/index.js')
|
||||
const { resp, codeMessage, APIError } = require('src/utils/response/index.js')
|
||||
const config = require('src/config/index.js')
|
||||
const { jwt } = require('src/utils/pkgs.js')
|
||||
const acl = require('src/utils/acl.js')
|
||||
const { copyObject } = require('src/utils/index.js')
|
||||
|
||||
const controller = {}
|
||||
module.exports = controller
|
||||
@ -34,6 +35,12 @@ controller.verifyCode = () => async (ctx) => {
|
||||
try {
|
||||
const token = await sso.getToken(code, sessionState)
|
||||
|
||||
if (!acl.checkAllow(token.groups)) {
|
||||
const copy = copyObject(resp.Forbidden)
|
||||
copy.object = codeMessage.CodeAccountNoPermission
|
||||
throw new APIError('account no permission', copy)
|
||||
}
|
||||
|
||||
// set accessToken/refreshToken cache
|
||||
cache.set(token.access_token, token.refresh_token, false)
|
||||
|
||||
|
@ -27,16 +27,6 @@ r.get(
|
||||
accCtrl.loginSSO()
|
||||
)
|
||||
|
||||
/**
|
||||
* account refresh token
|
||||
* @swagger
|
||||
* @route POST /api/refresh
|
||||
* @group account - account apis
|
||||
* @security JWT
|
||||
* @returns {RespDefault.model} default -
|
||||
*/
|
||||
r.post('/refresh', commonCtrl.authorization(true), accCtrl.logout())
|
||||
|
||||
/**
|
||||
* account logout
|
||||
* @swagger
|
||||
@ -45,7 +35,7 @@ r.post('/refresh', commonCtrl.authorization(true), accCtrl.logout())
|
||||
* @security JWT
|
||||
* @returns {RespDefault.model} default -
|
||||
*/
|
||||
r.post('/logout', commonCtrl.authorization(false), accCtrl.logout())
|
||||
r.post('/logout', commonCtrl.authorization(), accCtrl.logout())
|
||||
|
||||
/**
|
||||
* account get info
|
||||
@ -55,4 +45,4 @@ r.post('/logout', commonCtrl.authorization(false), accCtrl.logout())
|
||||
* @security JWT
|
||||
* @returns {RespDefault.model} default -
|
||||
*/
|
||||
r.get('/userinfo', commonCtrl.authorization(false), accCtrl.getInfo())
|
||||
r.get('/userinfo', commonCtrl.authorization(), accCtrl.getInfo())
|
||||
|
10
utils/acl.js
Normal file
10
utils/acl.js
Normal file
@ -0,0 +1,10 @@
|
||||
const ALLOW_GROUPS = new Set(['/professorx'])
|
||||
|
||||
const mod = {}
|
||||
module.exports = mod
|
||||
|
||||
mod.checkAllow = groups => {
|
||||
if (!Array.isArray(groups)) return false
|
||||
|
||||
return groups.filter(t => ALLOW_GROUPS.has(t)).length > 0
|
||||
}
|
@ -57,7 +57,8 @@ mod.codeMessage = {
|
||||
CodeUnauthorized: { code: 1004, message: 'unauthorized' },
|
||||
CodeForbidden: { code: 1005, message: 'forbidden' },
|
||||
CodeNotFound: { code: 1006, message: 'not found' },
|
||||
CodeInternalError: { code: 1007, message: 'internal error' }
|
||||
CodeInternalError: { code: 1007, message: 'internal error' },
|
||||
CodeAccountNoPermission: { code: 1008, message: 'account no permission' }
|
||||
}
|
||||
|
||||
mod.resp = {
|
||||
|
Loading…
Reference in New Issue
Block a user