我尝试实现基于令牌的身份验证方法:
每次成功登录都会创建新令牌。
如果用户选择“保持登录状态”或用户正在使用移动设备,则令牌将保留在Redis数据库中而不会过期。否则,令牌将在20分钟后过期。
用户通过身份验证后,会在我的Redis数据库中的每个后续请求中检查令牌。
我想知道如何识别设备。对于移动设备,我可以使用设备标识符。但是如何识别浏览器呢?
示例:用户使用Chrome登录并选择“让我登录”。使用Redis中的浏览器名称生成并保留令牌。如果用户从Firefox登录,则将令牌和“Firefox”保存在数据库中。我在Redis中保存令牌,而在成功验证时创建令牌。是否可以仅使用令牌和使用令牌的浏览器?或者我是否也需要保留IP?
其他问题:如何避免攻击者从cookie中窃取令牌?
答案 0 :(得分:20)
简而言之,基于令牌的身份验证方案遵循以下步骤:
在REST应用程序中,从客户端到服务器的每个请求都必须包含服务器要理解的所有必要信息。有了它,您不依赖于存储在服务器上的任何会话上下文,也不会破坏Roy T. Fielding在stateless constraint中定义的REST架构的dissertation:
[...]从客户端到服务器的每个请求必须包含理解请求所需的所有信息,并且不能利用服务器上任何存储的上下文。因此,会话状态完全保留在客户端上。 [...]
访问需要身份验证的受保护资源时,每个请求必须包含所有必要的数据才能进行正确身份验证/授权。这意味着将对每个请求执行身份验证。
请查看RFC 7235关于新身份验证方案注意事项的引用:
5.1.2. Considerations for New Authentication Schemes
HTTP身份验证框架的某些方面 对新身份验证方案的工作方式施加限制:
- HTTP认证被认为是无状态的:所有的 必须提供验证请求所需的信息 在请求中,而不是依赖于服务器记住 先前的请求。 [...]
身份验证数据(凭据)应属于标准HTTP Authorization
标头。来自RFC 7235:
Authorization
标头字段允许用户代理进行身份验证 本身与原始服务器 - 通常,但不一定,后 收到401
(未经授权)回复。它的价值包括 包含用户身份验证信息的凭据 代理请求的资源领域。Authorization = credentials
[...]
请注意,此HTTP标头的名称很不幸,因为它带有身份验证数据而不是授权。无论如何,这是发送凭据的标准标题。
执行基于令牌的身份验证时,令牌是您的凭据。在此方法中,您的硬凭证(用户名和密码)将交换为在每个请求中发送的令牌。
身份验证令牌是服务器生成的一段数据,用于标识用户。基本上,令牌可以是 opaque (除了值本身之外没有显示任何细节,如随机字符串)或者可以自包含(喜欢 JSON Web Token ):
随机字符串:可以通过生成随机字符串并将其持久保存到具有过期日期且与其关联的用户标识符的数据库来发出令牌。
< / LI> JSON网络令牌(JWT):由RFC 7519定义,它是在双方之间安全地表示声明的标准方法。 JWT是一个独立的令牌,使您能够在有效负载中存储用户标识符,到期日期和任何您想要的内容(但不要存储密码),这是{{3编码为JSON。客户端可以读取有效负载,并且可以通过验证服务器上的签名来轻松检查令牌的完整性。如果您不需要跟踪JWT令牌,则不需要坚持使用JWT令牌。尽管如此,通过持久存在令牌,您将有可能使其无效并撤销其访问权限。要保持跟踪JWT令牌,而不是保留整个令牌,您可以保留令牌标识符(Base64声明)和一些元数据(您发出令牌的用户,到期日期等),如果您需要。要找到一些与JWT合作的优秀资源,请查看jti
。
提示:始终考虑删除旧令牌,以防止数据库无限期增长。
您永远不会接受您的应用程序未发布的过期令牌或令牌。如果您使用的是JWT,则必须检查令牌签名。
请注意,一旦您发出令牌并将其交给您的客户,您就无法控制客户端对令牌的处理方式。 无法控制。 严重
检查http://jwt.io标头字段以告知正在使用哪个浏览器访问您的API是一种常见做法。但是,值得一提的是,HTTP标头可以轻松欺骗,您应该从不信任您的客户。浏览器没有唯一标识符,但如果您愿意,可以获得良好的User-Agent
级别。
我不了解您的安全要求,但您始终可以在服务器中尝试以下操作来增强API的安全性:
通过网络发送敏感数据时,您最好的朋友是HTTPS,它可以保护您的应用免受Spring的攻击。</ p>
顺便问一下,我提到过你永远不要相信你的客户吗?
答案 1 :(得分:0)
一旦服务器从客户端收到请求,它就包含User-Agent。此属性将帮助我们识别客户端。
请参阅此链接:How do I detect what browser is used to access my site?