Typescript 如何在LoopBack4中处理特定于请求/会话的数据

Typescript 如何在LoopBack4中处理特定于请求/会话的数据,typescript,express,loopbackjs,loopback4,Typescript,Express,Loopbackjs,Loopback4,目前,我在LoopBack4应用程序中遇到了一个问题。我们有一些控制器。我们正在使用JWT进行授权。在令牌有效负载中,我们存储了一个为请求用户授予的权限列表。此外,我们还添加了一个AuthorizationInterceptor来检查权限 我犯了一个错误,将令牌数据写入一个静态变量,并从应用程序中的服务和其他位置请求它。如果有并发请求传入,一个请求将覆盖另一个请求的令牌。请求A现在正在使用请求B的权限 问题: 客户端向包含令牌的LB4应用程序发出请求 应用程序将令牌存储在静态变量中 同时,传入

目前,我在LoopBack4应用程序中遇到了一个问题。我们有一些控制器。我们正在使用JWT进行授权。在令牌有效负载中,我们存储了一个为请求用户授予的权限列表。此外,我们还添加了一个AuthorizationInterceptor来检查权限

我犯了一个错误,将令牌数据写入一个静态变量,并从应用程序中的服务和其他位置请求它。如果有并发请求传入,一个请求将覆盖另一个请求的令牌。请求A现在正在使用请求B的权限

问题:

  • 客户端向包含令牌的LB4应用程序发出请求
  • 应用程序将令牌存储在静态变量中
  • 同时,传入请求B传输不同的令牌
  • 应用程序用请求B的令牌覆盖请求A的令牌
  • 请求A与请求B的权限一起工作
应用程序:

每个控制器:

导出类控制器
{
构造函数(@inject(AServiceBindings.VALUE)public-aService:aService){
@获取('/hasright',{})
@authenticate('jwt',{“required”:[1,2,3]})//这由AuthorizationInterceptor检查
异步getVersion():承诺
{
返回{hasRight:JWTService.checkRight(4)};
}
}
jwt服务:

导出类JWTService实现令牌服务
{
静态AuthToken:AuthToken | null;
静态权限:编号[];
//构造器。。。
/**一种检查权限的方法*/
静态hasRight(rightId:number):布尔值
{
返回inArray(rightId,JWTService.rights);
}
异步验证令牌(令牌:字符串):承诺
{
//验证令牌。。。
//将令牌数据写入静态变量
JWTService.AuthToken=AuthToken;
JWTService.rights=rightId;
返回userProfile;
}
}
导出常量JWTServiceBindings={
值:BindingKey.create(“services.JWTService”)
};
拦截器

@globalInterceptor(“”,{tags:{name:'authorize'}})
导出类AuthorizationInterceptor实现提供程序
{
建造师(
@注入(AuthenticationBindings.METADATA)公共元数据:AuthenticationMetadata,
@inject(TokenServiceBindings.USER_PERMISSIONS)受保护的检查权限:UserPermissionsFn,
@inject.getter(AuthenticationBindings.CURRENT_用户)公共getCurrentUser:getter
) {}
/**
*环回上下文使用此方法生成拦截器函数
*用于装订。
*
*@返回一个拦截器函数
*/
值()
{
返回this.intercept.bind(this);
}
/**
*拦截调用的逻辑
*@param invocationCtx-调用上下文
*@param next-调用下一个拦截器或目标方法的函数
*/
异步截获(invocationCtx:InvocationContext,next:()=>ValueOrPromise)
{
如果(!this.metadata)
{
返回next();
}
const requiredpowpermissions=this.metadata.options作为requiredpowpermissions;
const user=wait this.getCurrentUser();
如果(!this.checkPermissions(user.permissions,requiredPermissions))
{
抛出新的HttpErrors.Forbidden('权限被拒绝!您没有请求此函数所需的权限');
}
返回next();
}
}
JWTAuthenticationStrategy

导出类JWTAuthenticationStrategy实现AuthenticationStrategy
{
名称='jwt';
构造函数(@inject(JWTServiceBindings.VALUE)公共令牌服务:JWTService){}
异步身份验证(请求:请求):承诺
{
const-token:string=this.extractCredentials(请求);
返回此.tokenService.verifyToken(令牌);
}
//提取凭证等。。。
}
应用软件

导出类MyApplication扩展了BootMixin(ServiceMixin(RepositoryMixin(RestApplication))) { 构造函数(选项:ApplicationConfig={}) { 超级(期权); //绑定身份验证组件相关元素 此.component(AuthenticationComponent); registerAuthenticationStrategy(这是JWTAuthenticationStrategy); this.bind(JWTServiceBindings.VALUE).toClass(JWTService); this.bind(TokenServiceBindings.USER_PERMISSIONS).toProvider(UserPermissionsProvider); this.bind(TokenServiceBindings.TOKEN\u SECRET).to(TokenServiceConstants.TOKEN\u SECRET\u VALUE); //设置自定义序列 这个序列(MySequence); //还有更多的绑定和其他事情要做。。。 } } 序列号

导出类MySequence实现SequenceHandler
{
//构造器。。。
异步句柄(上下文:RequestContext)
{
//const session=this.restoreSession(context);//restoreSession不是函数。
尝试
{
const{request,response}=context;
const route=this.findulote(请求);
//调用身份验证操作
等待此消息。authenticateRequest(请求);
userId=getMyUserId();//使用helper方法
//身份验证成功,继续调用控制器
const args=wait this.parseParams(请求、路由);
const result=wait this.invoke(路由,参数);
发送(响应、结果);
}
捕捉(错误)
{
拒绝(上下文、错误);
}
最后
{
//使用用户ID p.e.的某些操作。。。
}
}
}
helper.ts//一个包含小函数的简单文件

导出函数getMyUserId():number
{
返回((JWTService.AuthToken&&JWTService.AuthToken.UserId)| 0);
}
除此之外,我们还实现了一些服务来处理大型事务