nestjs 使用jwt实现认证

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nestjs 使用jwt实现认证相关的知识,希望对你有一定的参考价值。

参考技术A JSON WEB TOKEN 用来解决跨域认证的问题,服务器认证后,生成JSON对象返回给客户端,服务器不保存session数据,所有数据都保存在客户端,每次请求都发回给服务器.

http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

官方规定了7个官方字段

除了官方字段,可更具自己的服务自定义字段如:

对前面两个部分的签名。防止数据被篡改。使用header中指定的签名算法(默认是HMAC SHA256),按照下面的公式产生签名

user.controller.ts

auth.service.ts:

auth.module.ts

jwt.strategy.ts:

参考:
https://juejin.im/post/6844904097317912584

NestJS 在 e2e 测试中模拟 JWT 身份验证

【中文标题】NestJS 在 e2e 测试中模拟 JWT 身份验证【英文标题】:NestJS mock JWT authentication in e2e tests 【发布时间】:2019-12-28 22:48:02 【问题描述】:

我想在我的 NestJS e2e(集成)测试中模拟 JWT 身份验证。我在我的业务逻辑中使用注入的令牌数据,我不想在我的测试代码中插入凭据。

我根据Nest authentication docs 实现了 JWT 身份验证。我在示例中使用了与 @User 装饰器类似的装饰器,并在我的业务逻辑中使用了有关 User 对象的信息。

@Post()
async myPostEndpoint(@Body() body: PostBody, @User() user: MyUser)
    // do stuff using user properties

在使用Nest testing docs 中所示的超测试测试我的应用程序时,我不想发出真正的身份验证请求,因为我需要在我的版本控制系统中保留凭据。

我希望能够覆盖提供者以返回测试用户。但想不通。

我尝试覆盖AuthServicevalidateClientlogin 以使用overrideProvider + useClass/useFactory/useValue 返回默认用户,如Nest testing docs 所示。我还尝试了覆盖 JwtStrategyLocalStrategy 中的方法,但请求仍然返回 401 - 未经授权。

【问题讨论】:

这有帮助吗? ***.com/questions/53267536/testing-passport-in-nestjs 不幸的是,接受的答案中的实现不会模拟用户。相反,它会执行一个真正的身份验证请求.post('/auth/login'),这是我想避免的,因为我需要将凭据放入我的测试代码中。 我想我在身份验证代码中添加了process.env.NODE_ENV 签入以处理这种情况。 【参考方案1】:

在您的 overrideGuard(AuthGuard('jwt')).useValue() 中,您可以向您的 canActivate() 函数添加功能,如下所示:

canActivate (context: ExecutionContext) => 
  const req = context.switchToHttp().getRequest();
  req.user = myCustomUserObject;
  return true;

其中myCustomUserObject 是服务器要处理的req.user 的预期值。

【讨论】:

嘿嘿,我试过你的答案,但我得到“无法设置未定义的属性'用户'”。 “req”值未定义... :( 我做了同样的事情,没有像@MirceaBaicu 所说的那样得到任何错误,但是在该API上注册的下一个守卫没有检测到属性user on req,因此禁止。有什么线索吗? 为什么不使用测试用户并创建 JWT,我认为 e2e 测试应该接近真实应用程序 从技术上讲,这将是更好的选择@MADforFUNandHappy,但由于问题是专门关于嘲笑守卫的,我想我会回答这个问题。 非常感谢,我试图模拟 AuthGuard 本身,但它没有成功。【参考方案2】:

一些具体情况,我们需要动态覆盖canActivate(例如覆盖不同的'users') 所以我只是像这样开玩笑地嘲笑了“jsonwebtoken”模块

jest.mock('jsonwebtoken', () => (
  verify: jest.fn((token, secretOrKey, options, callback) => 
    callback(null, 
      payload: 
        email: 'any@email.com',
        sub: 1,
      ,
      header: 'header',
      signature: 'signature',
    );
  ),
));

【讨论】:

【参考方案3】:

对于使用 GraphQL 的人,这是我所做的:

const module: TestingModule = await Test.createTestingModule(
      imports: [AppModule],
    )
      .overrideGuard(JwtAuthGuard)
      .useValue(
        canActivate: (context: ExecutionContext) => 
          const ctx = GqlExecutionContext.create(context)
          ctx.getContext().req.user =  user_id: "abc123"  // Your user object
          return true
        ,
      )
      .compile()

【讨论】:

以上是关于nestjs 使用jwt实现认证的主要内容,如果未能解决你的问题,请参考以下文章

JWT认证在Django中的简单实现

JWT实现授权认证

SpringBoot集成JWT实现权限认证

springboot+jwt实现token登陆权限认证

使用JWT实现Token认证

DRF-jwt认证