NestJs/Angular/Cognito 流 [英] NestJs/Angular/Cognito flow

查看:99
本文介绍了NestJs/Angular/Cognito 流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果没有具体示例,很难正确理解身份验证和授权流程.NestJs doc 有一个很好的 JWT 令牌示例,但是我发现很难建立正确的流程.

这是我能够解决授权流程的最接近的方法:

  1. 身份验证后,将刷新令牌存储在数据库中(我不太喜欢但找不到更简单的方法来处理它),将访问令牌发送到 Angular 并将其保存在本地存储或 cookie 中
  2. 在每个请求中发送访问令牌并检查它是否仍然有效且未接近到期;如果它已过期或即将过期,则转到数据库,获取刷新令牌并使用它来获取新的访问令牌.我也非常希望将刷新令牌存储在 cookie 中,但问题是我不知道在实现 JwtStrategy 时如何获得多于 Authorization 标头,以及什么是最好的(如果有的话)附加方式刷新令牌
  3. 如果访问令牌已更新,请以某种方式将其发送回 Angular 端以进行替换.也发送过期时间,因此如果有并发请求,Angular 端不会用旧的访问令牌替换新的访问令牌.但是并发请求仍然有可能遇到竞争条件,并且每个请求都单独请求访问令牌.

上面的摘要中遗漏了很多细节,但这应该可以提供我正在尝试实施的整体流程.我现在面临的两个挑战是:

  1. 多个并发请求的可能性,都发现访问令牌即将过期并尝试立即刷新.
  2. 如何在 JwtStrategy 本身中将新的访问令牌和到期时间戳添加到响应标头(或正文,如果它应该在那里),以便可以使用单个注释/保护处理整个身份验证周期.

如果有人可以帮助解决上述两个问题,我将不胜感激.

此外,我不确定它是否符合 SO 政策,但由于 NestJs/Angular/Cognito 组合没有可靠的材料,而且身份验证是安全网页最重要的部分.我很乐意为能够在 github 中提供完整工作示例的人提供一些奖励,该示例充分展示了如何使用最佳实践实现身份验证和授权(访问和刷新令牌)流程.

最后,这是迄今为止我为 NestJs/Cognito 组合找到并使用的最好的(唯一的?)资源;没有人能真正回答上述问题.

解决方案

流程应该是

<块引用>

  1. 注册/登录后,更新数据库中该用户记录中存储的刷新令牌.然后后端将带有访问令牌和刷新令牌的数据返回给前端.

<块引用>

  1. 请求需要身份验证的端点时,请验证存储在身份验证标头中的 jwt 令牌.如果验证成功,返回数据;否则,返回未经授权的请求错误.

<块引用>

  1. 前端从后端接收需要认证的数据.如果是有效数据,则不要请求刷新访问令牌端点,否则请求后端并通过提供本地存储的刷新令牌来请求新的访问令牌.

<块引用>

  1. 当后端收到刷新访问令牌请求时,它会检查三个方面:

1、数据库中的用户记录上是否存储了刷新令牌?2、这个刷新令牌有效吗?3、刷新令牌是否过期?

如果刷新令牌有效且未过期,则向前端返回一个新的访问令牌.

否则,向前端报告错误.

前端以这种方式对刷新的访问令牌做出反应

<块引用>

  1. 获取更新的访问令牌;它在本地刷新访问令牌
  2. 出现错误,清除本地数据,并要求用户重新登录.

<块引用>

  1. 当用户退出时,删除数据库中该用户记录中存储的刷新令牌和过期时间.

我也有一个示例 https://github.com/katesroad/Roles_Based_Sample/树/主/后端.

请检查 auth.controller.ts 和 strategy 文件夹.

The Authentication and Authorization flows are difficult to get right without concrete examples. NestJs doc has a good example for JWT tokens, however I find it difficult to establish the correct flow.

Here is the closest I have been able to get to solve the authorization flow:

  1. after authentication, store refresh token in DB (which I don't like much but couldn't find an easier way to handle it), send access token to Angular and keep it in local storage or a cookie
  2. On every request send the access token and check if it's still valid and not close to expiry; if it's expired or about to expire, then go to the DB, get the refresh token and use it to acquire a new access token. I would very much liked to have refresh token stored in a cookie too, but the problem with that is that I don't know how to get more than Authorization header when implementing the JwtStrategy, and what's the best (if any) way to attach the refresh token
  3. If access token is updated, somehow send it back to the Angular side to be replaced. send the expired time as well so Angular side doesn't replace a newer access token with an older one if there are concurrent requests. But concurrent requests still have a chance of running into a race condition and each, separately, requesting an access token.

There are a bunch of details that are missing in the summary above, but that should give the overall flow that I am trying to implement. The two challenges I have right now is:

  1. The possibility of multiple concurrent requests, all finding out that access token is about to expire and trying to refresh it at once.
  2. How to add the new access token and expiry timestamp to response header (or body if it should be there), in JwtStrategy itself so the whole auth cycle can be handled with one single annotation/guard.

I appreciate if somebody can help with the above two questions.

Also, I am not sure if it complies with SO policies, but since there is no solid material for the NestJs/Angular/Cognito combination, and since auth is the most important part of a secure webpage. I will be happy to grant some bounties for someone who can put a full working example in github that demonstrates fully how both authentication and authorization (both access and refresh tokens) flows are implemented using best practices.

Finally, here are the best (only?) resources I have found and used so far for NestJs/Cognito combo; none really get to answer the above questions.

解决方案

The flow should be

  1. After signing up/in, update the refresh token stored on that user record in database. Then backend returns data with an access-token and refresh-token to the frontend.

  1. When requesting an endpoint that requires authentication, verify the jwt token stored in the authentication header. If verified successfully, return data; otherwise, return unauthorized request error.

  1. The frontend receives the data that requires authentication from the backend side. If it is with valid data, don't request the refresh access token endpoints, otherwise request backend and ask for a new access token by providing refresh token stored locally.

  1. When the backend receives a refreshing access token request, it checks three aspects:

1, Is there a refresh token stored on that user record in DB? 2, Is this refresh token is valid? 3, Is the refresh token expired?

If the refresh token is valid and unexpired, return a new access token to the frontend.

Otherwise, report the error to the frontend.

The frontend reacts to the refreshing access token in this way

  1. Get a renewed access token; it refreshes the access token locally
  2. Get an error, clear local data, and require the user to sign in again.

  1. when the user signs out, delete the refresh token and expire time stored on that user record in the database.

I also have a sample https://github.com/katesroad/Roles_Based_Sample/tree/main/backend.

Please check the auth.controller.ts and strategies folder.

这篇关于NestJs/Angular/Cognito 流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆