使用 nodejs 应用程序上的刷新和访问令牌了解身份验证流程

Posted

技术标签:

【中文标题】使用 nodejs 应用程序上的刷新和访问令牌了解身份验证流程【英文标题】:Understanding authentication flow with refresh and access tokens on nodejs app 【发布时间】:2016-01-30 02:00:14 【问题描述】:

我知道已经有很多关于 Oauth、Oauth2、JWT 等的帖子。我已经阅读了很多,但我比以往任何时候都更加困惑,所以我正在寻找一些澄清。我将提出我对该主题的看法,我希望有人能告诉我我的实现是否足够安全,或者我做错了什么以及如何改进它。

我正在构建一个 API Rest 服务器来为我的用户提供我的资源。假设它是一个银行应用程序,用户可以在其中存款、取款和转账。

我正在为我的服务器使用 nodejs、hapijs、jsonwebtokens 和 bcrypt。我想实现两个令牌认证流程(Oauth2)。

这就是我的做法:

    用户通过提供一些凭据(用户名和密码)登录到身份验证服务器。

    服务器验证用户的凭据,如果它们有效,它将授予用户访问权限并返回一个刷新令牌和一个访问令牌。

    这些令牌保存在浏览器或移动设备的本地存储中。

    access token:

    被签名为 jsonwebtoken。 包含发布日期、到期日期(5 分钟)、用户数据(ID、用户名)。

    refresh token:

    被签名为 jsonwebtoken 并使用 bcrypt 加密。 包含唯一标识符 可能包含到期日期 保存在数据库中。

    只要access token是有效的,也就是说,它没有过期并且包含有效的用户数据,资源服务器就会为用户提供所请求的资源。

    access token 不再有效时,身份验证服务器请求客户端提供refresh token 以便发出新的access token

    服务器从用户那里收到refresh token,对其进行解密,将其与数据库中的比较,检查它是否已被撤销,并检查其唯一标识符。 如果refresh token 通过所有测试,服务器会向客户端发出一个新的access token。 如果refresh token 未能通过一项测试,服务器会请求用户重新进行身份验证。

注意事项:我试图避免使用 cookie。

问题:

如果用户能够窃取access token,我猜它也可以窃取refresh token。那么,如何让refresh token 更安全? 我对 Oauth2 流程的看法是否正确? 我可以改进什么? 我错过了什么吗?

【问题讨论】:

什么样的客户会使用你的服务? @MvdD 我会说是公开的。 我阅读了更多关于客户端类型的信息,我不得不说两个客户端都会使用我的服务,我相信。我将有一个 web 应用程序,以及一个使用 react native 制作的原生应用程序;我不知道它是否被认为是原生的。我将使用 https。 @ElPirru 为什么要加密 refresh_token? 我也有同样的问题。我可以添加的另一个问题是“用户是否在他的请求中同时发送刷新/访问令牌?” 【参考方案1】:

OAuth2 之所以让很多人感到困惑,是因为它根据使用的客户端类型使用不同的身份验证流程。

OAuth2 区分两个client type,机密或公开。除此之外,还有 2 个基于重定向的授权流(授权代码和隐式),旨在与浏览器或浏览器控件一起使用。

其他两个流(资源所有者密码和客户端凭据)旨在用于非浏览器应用(CLI、后台服务、受信任的移动客户端)。

我在this answer here 中更详细地描述了不同的流程以及何时使用它们。

【讨论】:

以上是关于使用 nodejs 应用程序上的刷新和访问令牌了解身份验证流程的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS上的Facebook iOS access_token身份验证

了解 Google OAuth2 刷新令牌

访问令牌和刷新令牌最佳实践?如何实现访问和刷新令牌

JWT - 刷新令牌和安全改进

新帐户上的 Google API(分析)访问令牌和刷新令牌错误

访问令牌和刷新令牌流程