因此,我正在做一个基于角色的访问应用程序,并将用户的角色嵌入到JWT中。解码令牌时,得到id, role...
。现在,我有一个函数可以检查x-auth-token
标头中的令牌。这就是函数的样子。
export const decodeToken = (controller) => {
return wrapAsync(async (httpRequest) => {
const token = httpRequest.headers['x-auth-token']
if (!token) {
throw new UnauthorizedError('No token, authorization denied.')
}
const decoded = jwt.verify(token, process.env.JWT_SECRET)
httpRequest.user = decoded
return controller(httpRequest)
})
}
我还有一个函数也可以检查角色,它类似于decodeToken
函数,这就是roleCheck
函数的样子。
export function roleCheck(controller) {
return wrapAsync(async (httpRequest) => {
const token = httpRequest.headers['x-auth-token']
const decoded = jwt.verify(token, process.env.JWT_SECRET)
if (decoded.role !== 'admin') {
throw new UnauthorizedError(
'You do not have the authorization to perform this action'
)
}
return controller(httpRequest)
})
}
现在,这里有很多代码重复。我本可以解决此问题的一种方法是还检查decodeToken
函数中的角色,但是该方法将导致没有将admin
角色附加到传入负载的用户无法访问所有路由。现在我的问题是我该如何通过
const token = httpRequest.headers['x-auth-token']
const decoded = jwt.verify(token, process.env.JWT_SECRET)
从decodeToken
函数到roleCheck
函数。另外,这是功能组合的用例吗?我觉得代码可以比这干净得多,但我只是不知道如何实现。
通常,路线看起来像这样
export function config(router) {
router
.post('/', expressCallback(decodeToken(roleCheck(postProduct))))
.get('/', expressCallback(decodeToken(getProducts)))
...
return router
}
因此,首先调用decodeToken
,然后在请求到达roleCheck
控制器之前调用postProduct
。通过这种方式,可以从标头中获取令牌并对其进行解码,然后控制器可以根据角色进行操作。
感谢您的任何帮助。
答案 0 :(得分:1)
您要对令牌进行两次解码,而无需这样做。您正在对'decodeToken'中的令牌进行解码,并将新字段'user'附加到包含来自令牌的所有已解码信息的请求对象,角色等)。在'roleCheck'内部,您不需要再次解码令牌,因为您已经将所有已解码的信息存储在请求对象的'user'字段中。您要做的就是访问此信息并检查角色。
decodeToken:
export const decodeToken = (controller) => {
return wrapAsync(async (httpRequest) => {
const token = httpRequest.headers['x-auth-token']
if (!token) {
throw new UnauthorizedError('No token, authorization denied.')
}
const decoded = jwt.verify(token, process.env.JWT_SECRET)
httpRequest.user = decoded //here you are storing the info in user field of httpRequest
return controller(httpRequest)
})
}
现在将名称“ roleCheck”更改为类似“ adminRoleCheck”的名称,以检查用户是否为管理员。
adminRoleCheck:
export function adminRoleCheck(controller) {
return wrapAsync(async (httpRequest) => {
if (httpRequest.user.role !== 'admin') {
throw new UnauthorizedError(
'You do not have the authorization to perform this action'
)
}
return controller(httpRequest)
})
}
类似地定义其他功能(例如customerRoleCheck)来检查其他角色。您也不必担心代码重复,因为这些功能只需要在应用程序中定义一次即可。