当前位置: 首页 > 知识库问答 >
问题:

JWT身份验证

孙海
2023-03-14

我正在开发一个具有自己的身份验证和授权html" target="_blank">机制的REST应用程序。我想使用JSON Web Tokens进行身份验证。以下是有效且安全的实现吗?

    < li >将开发一个REST API来接受用户名和密码并进行认证。要使用的HTTP方法是POST,因此没有缓存。此外,在传输时还会有安全SSL < li >在认证时,将创建两个JWTs访问令牌和刷新令牌。刷新令牌将具有更长的有效期。这两个令牌都将写入cookies中,以便在每个后续请求中发送它们 < li >在每次REST API调用时,将从HTTP头中检索令牌。如果访问令牌未过期,请检查用户的权限并相应地允许访问。如果访问令牌已过期,但刷新令牌有效,请使用新的过期日期重新创建新的访问令牌和刷新令牌(进行所有必要的检查以确保用户的身份验证权限未被撤销)并通过Cookies发回 < li >提供注销REST API,该API将重置cookie,因此在登录完成之前,后续API调用将被拒绝。

我对刷新令牌的理解是:

由于刷新令牌的存在,我们可以保持更短的访问令牌有效期,并经常检查(在访问令牌到期时)用户是否仍被授权登录。

如果我错了,请纠正我。

共有3个答案

吕高寒
2023-03-14

像OP一样,我一直在使用资源所有者密码授权。

我从Saptarshi Basu在另一篇文章中的另一个答案中学到了很多东西,我认为任何研究OAuth代码流的人都应该看看它,它概述了一种非常可靠的身份验证SPA和资源服务器方法。它主要依赖于后端(资源服务器)来处理身份验证提供程序作为私有客户端的身份验证。

然而,我只想补充一点,希望用SPA实现身份验证的人也应该考虑用PKCE实现OAuth代码流。PKCE的主要目标是允许公共客户端(如SPA)直接通过身份验证提供者进行身份验证。PKCE补充的所有内容是,当SPA应用程序启动身份验证时,当用户经过身份验证时会将哈希值发送给身份验证提供者。在用户向授权提供商进行身份验证后,它将用户重定向回带有哈希值和授权代码的SPA。现在,在下一部分,SPA调用身份验证提供者以代码交换令牌,而不是提供客户端机密,它必须提供最初用于创建散列值的密钥。这种机制保证了代码不会被截获代码的人使用,而且SPA不需要像服务器端应用程序那样存储客户端机密。

现在,在这一点上,我唯一不确定的是哪一个在技术上更安全,是使用标准代码流的服务器端身份验证,而不是PKCE或SPA直接使用PKCE进行身份验证?我目前能在网上找到的大多数资源都描述并推荐后者。然而,我觉得让一个私有的服务器端客户端来处理认证(正如Saptarshi Basu所描述的)可能会更安全。我也很想听听他对此的看法。

孔君浩
2023-03-14

两年前我问过这个问题,也接受了答案。但是,根据我过去两年的经验和研究,我想回答这个问题,以防有人用同样的问题偶然发现这个线程

问题中提到的方法类似于OAuth 2.0的“资源所有者密码凭据”授权类型。但是,我认为最好使用“授权代码授权”类型和Cookie来存储令牌,而不是使用浏览器localStoragesessionStorage。我在这个StackOverw回答中详细说明了我的理由、实现要点、安全考虑和参考。

李弘光
2023-03-14

将开发一个REST API来接受用户名和密码并进行身份验证。要使用的HTTP方法是POST,因此没有缓存。此外,在运输时将使用SSL进行安全保护

这是大多数人的做法,所以你在这里很好。

在身份验证时,将创建两个JWT-访问令牌和刷新令牌。刷新令牌将具有更长的有效期。这两个令牌都将写入cookie中,以便在每次后续请求中发送它们

将令牌存储在 cookie 中 我本身并不危险,但是如果您以某种方式让服务器上的 JWT 模块从那里读取它们,您很容易受到 CSRF 攻击,任何网页都可以触发用户浏览器将表单发送到您的服务器,除非您使用 CSRF 令牌。因此,通常它们存储在localStorage中,并且每次都“手动”添加到请求标头中。

在每次REST API调用时,将从HTTP头中检索令牌。如果访问令牌未过期,请检查用户的权限并相应地允许访问。如果访问令牌已过期,但刷新令牌有效,则使用新的过期日期重新创建新的访问令牌和刷新令牌(进行所有必要的检查,以确保用户的身份验证权限未被撤销),并通过Cookies发回

除了饼干的危险,它似乎是安全的。

提供一个注销REST API,它将重置cookie,因此后续的API调用将被拒绝,直到登录完成。

您甚至不需要进行API调用,只需清除cookie或localStorage对象,并确保您的客户端不会因丢失的令牌而中断。

express-jwt 模块的标准希望令牌位于其自己的“授权:持有者 [令牌]”标头中,我强烈建议使用 cookie。localStorage API一直到IE8都可用,所以你应该很好。

编辑:

首先,重要的是要知道XSS和CSRF攻击之间的区别,因为它们通常被认为是一回事。

XSS 是指用户在其他用户浏览器中在您的域上运行不安全的 JS,当这种情况发生时,本地存储或会话中的 JWT 和 cookie 中的 JWT 都不安全。在 cookie 上使用 httpOnly 标志,您无法直接访问它们,但浏览器仍会将它们与 AJAX 请求一起发送到您的服务器。如果发生这种情况,您通常会不走运。为防止出现这种情况,请确保转义所有用户输入(如果将其发送到浏览器)。

如果您使用脚本标签或 iframe 加载第 3 方 JS,除非您小心,否则这可能会危及 localStorage,但我在这方面的工作还不够,无法为您提供帮助。

CSRF只有在其他域试图通过让浏览器自动发送cookies来向您的服务器发送普通HTML表单时才会出现。html" target="_blank">框架通过插入唯一的随机字符串作为隐藏字段并在提交时再次检查它们来防止这种情况。JWT的in localStorage是安全的,因为每个域都有自己独立的localStorage区域。

但最终这一切都取决于你的服务是否将使用一个单一的域,在这种情况下,httpOnly cookies将非常安全,也更容易设置,但如果你想将你的服务分散在多个域中,如api.domain.com app.domain.com或添加一个本地应用程序,你必须将你的jwt存储在本地存储或其他本地存储区域。

希望这有帮助!

 类似资料:
  • 在auth-routes示例中,api和nuxt一起启动并使用一个Node.js服务器实例。但是,有时我们应该使用jsonWebToken处理外部api身份验证问题。在这个例子中,将用最简单的方式解释。 官方 auth-module 如果要实现复杂的身份验证流程,例如OAuth2,我们建议使用官方 auth-module 结构 由于Nuxt.js同时提供服务器和客户端呈现,并且浏览器的cookie

  • 我必须说,我对整个模型非常困惑,我需要帮助把所有的浮动件粘在一起。 我不是在做Spring REST,只是简单的WebMVC控制器。 什么让人困惑?(错误之处请指正) 第三方身份验证 要针对第三方进行身份验证,我需要通过扩展AuthenticationProvider来拥有自定义提供程序 null 问题: 何时调用AbstractAuthenticationProcessingFilter#Suc

  • 我在做一个全堆栈的web应用程序。我的前端由angular-cli组成,后端由node+Express构建。

  • 我试图在我的Web API应用程序中支持JWT承载令牌(JSON Web令牌),但我迷路了。 我看到了对.NET核心和OWIN应用程序的支持。 我当前正在IIS中托管我的应用程序。 我如何在我的应用程序中实现这个身份验证模块?是否有任何方法可以使用配置,与使用Forms/Windows身份验证的方法类似?

  • 我正在使用SpringBoot开发具有微服务架构的Rest Backend。为了保护endpoint,我使用了JWT令牌机制。我正在使用Zuul API网关。 如果请求需要权限(来自JWT的角色),它将被转发到正确的微服务。Zuul api网关的“WebSecurityConfigrerAdapter”如下。 这样,我必须在这个类中编写每个请求授权部分。因此,我希望使用方法级安全性,即“Enabl

  • jwt不应该仅仅用于认证用户吗?我读到过可以在里面存储非敏感的东西,比如用户ID。将权限级别之类的东西存储在令牌中可以吗?这样我可以避免数据库调用。