gpt4 book ai didi

spring - REST API中基于 token 的身份验证

转载 作者:行者123 更新时间:2023-12-01 06:57:51 24 4
gpt4 key购买 nike

我试图实现基于令牌的身份验证方法:

  • 每次成功登录都会创建新令牌。
  • 如果用户选择“让我保持登录状态”或用户正在使用移动设备,则令牌将保留在Redis数据库中而没有到期日期。否则,令牌将在20分钟后过期。
  • 一旦用户通过身份验证,便会从我的Redis数据库中的每个后续请求中检查令牌。

  • 我想知道如何识别设备。对于移动设备,我可以使用设备标识符。但是,如何识别浏览器?

    示例:用户使用Chrome登录,然后选择“保持登录状态”。在Redis中,将生成一个令牌并将其保留为浏览器名称。如果用户从Firefox登录,则将令牌和“Firefox”保存在数据库中。我将令牌保存在Redis中,而令牌是在成功身份验证后创建的。仅保留令牌和使用令牌的浏览器是否还可以?还是我也需要保留IP?

    附加问题:如何避免攻击者从cookie中窃取令牌?

    最佳答案

    基于令牌的身份验证如何工作

    简而言之,基于令牌的身份验证方案遵循以下步骤:

  • 客户端将其凭据(用户名和密码)发送到服务器。
  • 服务器对凭据进行身份验证并生成令牌。
  • 服务器将先前生成的令牌以及用户标识符和到期日期存储在某个存储器中。
  • 服务器将生成的令牌发送到客户端。
  • 在每个请求中,客户端都将令牌发送到服务器。
  • 服务器在每个请求中均从传入请求中提取令牌。服务器使用令牌来查找用户详细信息以执行身份验证和授权。
  • 如果令牌有效,则服务器接受请求。
  • 如果令牌无效,则服务器拒绝该请求。
  • 服务器可以提供一个端点来刷新令牌。

  • 如何将凭证发送到服务器

    在REST应用程序中,从客户端到服务器的每个请求必须包含服务器必须理解的所有必要信息。有了它,您将不依赖于存储在服务器上的任何会话上下文,也不会破坏Roy T. Fielding在其 stateless constraint中定义的REST体系结构的 dissertation:

    5.1.3 Stateless

    客户端到服务器的每个请求都必须包含理解该请求所需的所有信息,并且不能利用服务器上任何已存储的上下文。因此,会话状态完全保留在客户端上。 [...]

    当访问需要身份验证的受保护资源时,每个请求必须包含所有需要正确身份验证/授权的必要数据。这意味着将对每个请求执行身份验证。

    看看 RFC 7235中有关新身份验证方案的注意事项的报价:

    5.1.2. Considerations for New Authentication Schemes

    HTTP身份验证框架的某些方面
    对新的身份验证方案如何工作设置了限制:


  • HTTP身份验证被认为是无状态的:所有
    必须提供验证请求所需的信息
    在请求中,而不是依赖于服务器的记忆
    事先要求。 [...]


  • 身份验证数据(凭证)应属于标准HTTP Authorization 标头。从 RFC 7235:

    4.2. Authorization

    Authorization标头字段允许用户代理进行身份验证
    本身带有原始服务器-通常(但不一定)在
    收到 401(未经授权)响应。其值包括
    包含用户身份验证信息的凭据
    所请求资源领域的代理。

    Authorization = credentials

    [...]

    请注意,此HTTP标头的名称很不幸,因为它带有身份验证数据而不是授权数据。无论如何,这是用于发送凭据的标准标头。

    在执行基于令牌的身份验证时,令牌是您的凭据。用这种方法,您的硬凭证(用户名和密码)将交换为在每个请求中发送的令牌。

    令牌看起来像什么

    身份验证令牌是服务器生成的用于标识用户的一条数据。基本上,令牌可以是不透明的(除了值本身,不显示任何细节,例如随机字符串),也可以是独立的(例如JSON Web令牌):
  • 随机字符串:可以通过生成随机字符串并将其具有到期日期和与之关联的用户标识符持久保存到数据库中来发行令牌。
  • JSON Web令牌(JWT):由RFC 7519定义,这是一种用于在双方之间安全地表示声明的标准方法。 JWT是一个自包含的令牌,使您能够在有效负载中存储用户标识符,有效期和任何您想要的内容(但不存储密码),该有效负载是JSON编码为Base64。客户端可以读取有效负载,并且可以通过在服务器上验证其签名轻松地检查令牌的完整性。如果不需要跟踪JWT令牌,则无需持久化它们。虽然如此,通过保留令牌,您将有可能使令牌无效并撤销它们的访问。要跟踪JWT令牌,而不是持久保留整个令牌,可以根据需要持久化令牌标识符( jti 声明)和一些元数据(您为其发布令牌的用户,到期日期等)。要查找与JWT一起使用的大量资源,请查看http://jwt.io

  • 提示:始终考虑删除旧令牌,以防止数据库无限期增长。

    如何接受代币

    您绝不接受过期的令牌或应用程序未发行的令牌。如果使用的是JWT,则必须检查令牌签名。

    请注意,一旦您发行了令牌并将其提供给客户,您将无法控制客户对令牌的处理方式。无控制。说真的

    通常,检查 User-Agent 标头字段以告诉使用哪个浏览器访问您的API。但是,值得一提的是,HTTP标头很容易被欺骗,因此您永远不应信任客户端。浏览器没有唯一的标识符,但是如果您愿意的话,可以获得很好的 fingerprinting级别。

    我不知道您的安全要求,但是您始终可以在服务器中尝试以下操作,以增强API的安全性:
  • 检查颁发令牌时用户使用的浏览器。如果浏览器在以下请求中不同,则拒绝令牌。
  • 获取颁发令牌时的客户端远程地址(即客户端IP地址),并使用第三方API查找客户端位置。例如,如果以下请求来自其他国家/地区的地址,请拒绝该令牌。要按IP地址查找位置,可以尝试使用免费的API,例如MaxMind GeoLite2IPInfoDB。请注意,对于您的API收到的每个请求都打入第三方API并不是一个好主意,并且可能会对性能造成严重损害。但是您可以通过存储客户端远程地址及其位置来最大程度地减少缓存的影响。如今有一些缓存引擎可用。仅举几例:GuavaInfinispanEhcacheSpring

  • 通过网络发送敏感数据时,最好的朋友是HTTPS,它可以防止 man-in-the-middle attack保护您的应用程序。

    顺便说一句,我是否提到过您不应该信任您的客户?

    关于spring - REST API中基于 token 的身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36273905/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com