我正在尝试冒泡一个来自jsonwebtoken中的verify函数的错误,但是,它包装了另一个我希望的内部500状态错误,而不是未经授权的错误。 大多数组件都内置在Loopback-next身份验证组件中。下面的类是一个名为AuthenticationStrategy的类的提供程序。 AuthenticationStrategy只是一个带有通行证策略的类,该策略返回一个Authentication Strategy,该策略在路由的元数据上传递。在下面的类中(身份验证策略类型的提供程序,value()是调用提供程序时返回的函数。护照策略验证功能必须首先转换为身份验证策略,然后通过value函数返回给提供程序。调用value()时,verify函数将在路由的元数据(本例中为承载令牌)上运行。下面的函数cb与普通护照策略中的“ done”函数相同,并返回(错误,对象)
import {AuthenticateErrorKeys} from '../error-keys';
import {RevokedTokenRepository,UserRepository} from '../../../repositories';
import {repository} from '@loopback/repository';
import {Strategy} from 'passport-http-bearer'
import {HttpErrors} from '@loopback/rest';
import {StrategyAdapter} from '@loopback/authentication-passport'
import {AuthenticationStrategy} from '@loopback/authentication'
import {inject,Provider} from '@loopback/context'
var verify = require('jsonwebtoken').verify
export const BEARER_AUTH_STRATEGY = 'bearer';
export class PassportBearerauthProvider implements Provider<AuthenticationStrategy> {
constructor(
@repository(RevokedTokenRepository)
public revokedTokenRepository: RevokedTokenRepository,@repository(UserRepository)
public userRepository: UserRepository,){}
value(): AuthenticationStrategy {
const bearerStrategy = new Strategy(this.verify.bind(this));
return this.convertToAuthStrategy(bearerStrategy);
}
async verify (token: string,cb: Function){
try{
if (token && (await this.revokedTokenRepository.get(token))) {
throw new HttpErrors.Unauthorized(AuthenticateErrorKeys.TokenRevoked);
}
const userauthToken = await verify(token,process.env.JWT_SECRET as string,{
issuer: process.env.JWT_ISSUER,})
let authUser = await this.userRepository.getauthUser(userauthToken.id)
return cb(null,authUser)
}
catch(error) {
if (error.name && error.name === "JsonWebTokenError") {
return cb(new HttpErrors.Unauthorized(AuthenticateErrorKeys.TokenInvalid),null)
}
if (error.name && error.name === "TokenExpiredError") {
return cb(new HttpErrors.Unauthorized(AuthenticateErrorKeys.TokenExpired),null)
}
if (error.code && error.code === "ENTITY_NOT_FOUND") {
return cb(new HttpErrors.Unauthorized(`${AuthenticateErrorKeys.UserDoesnotExist},id: ${error.entityId}`),null)
}
return cb(error,null)
}
}
// Applies the `StrategyAdapter` to the configured basic strategy instance.
// You'd better define your strategy name as a constant,like
// `const AUTH_STRATEGY_NAME = 'basic'`
// You will need to decorate the APIs later with the same name
convertToAuthStrategy(bearer: Strategy): AuthenticationStrategy {
return new StrategyAdapter(bearer,BEARER_AUTH_STRATEGY);
}
}
以下序列在有人提出API请求时运行。如果在路由上方,则使用@authenticate [BEARER_AUTH_TOKEN]装饰该路由,调用上面的提供程序,然后对元数据运行verify函数。
export class MySequence implements SequenceHandler {
constructor(
@inject(Sequenceactions.FIND_ROUTE) protected findRoute: FindRoute,@inject(Sequenceactions.PARSE_PARAMS) protected parseParams: ParseParams,@inject(Sequenceactions.INVOKE_METHOD) protected invoke: InvokeMethod,@inject(Sequenceactions.SEND) public send: Send,@inject(Sequenceactions.REJECT) public reject: Reject,@inject(AuthorizationBindings.AUTHORIZE_actION)
protected checkAuthorisation: AuthorizeFn,@inject(AuthenticationBindings.AUTH_actION)
protected authenticateRequest: AuthenticateFn,) {}
async handle(context: RequestContext) {
try {
const {request,response} = context;
const route = this.findRoute(request);
const args = await this.parseParams(request,route)
const authUser = await this.authenticateRequest(request).catch(error => {
Object.assign(error,{statusCode: 401,name: "NotAllowedaccess",message: (error.message && error.message.message)? error.message.message: "Unable to Authenticate User" });
throw error
})
console.log(authUser)
const isaccessAllowed: boolean = await this.checkAuthorisation(
authUser && authUser.permissions,request,);
if (!isaccessAllowed) {
throw new HttpErrors.Forbidden(AuthorizeErrorKeys.NotAllowedaccess);
}
const result = await this.invoke(route,args);
this.send(response,result);
} catch (error) {
this.reject(context,error);
}
}
}
但是当它捕获到错误时,状态为500,并且401未经授权错误被包装在内部状态错误中。我该如何返回401错误? 我有更多类似这样的情况,其中的错误更加严重,因此我正在尝试采用严格的实现。