angular - 带有刷新 token 的 JSON Web token 身份验证逻辑

标签 angular security oauth-2.0 authorization jwt

在浏览器(网站后端)中运行的 Angular 4 应用程序,显示来自特定用户拥有的服务器数据。
服务器:PHP+MySQL,Zend Framework 3 + Doctrine ORM

命名:

  • access_token :生命周期短(1 分钟),允许访问个人资源,携带 user_id,base64 编码,json 网络 token 规范有效。
  • refresh_token :长生命周期(1 周)允许在不提供凭据的情况下检索新的 access_token,存储在 db 中,如果需要,管理员可以撤销。

  • 使用refresh_tokens的要点是登录时间超过access_token生命周期短(如果 refresh_token 过期时间在每次用户授权发生时更新,则可能永远),只有在不活动时间长于 refresh_token 的情况下,用户才需要提供凭据。生命周期。
    刷新 token 存储在 db 中,因此可以轻松撤销。

    1. 浏览器尝试验证

    要求:
  • 用户名和密码
  • 发送到/api/auth

  • 回复:

    验证用户名和密码并对照数据库检查

    如果有效:
  • access_token生成的过期时间为 60 秒
  • user_id被编码为 access_token
  • refresh_token生成(随机字符串)并保存到db,过期时间1周,(refresh_token不包含在access_token中,它是一个单独的 key )
  • HTTP 200 正常

  • 如果无效:
  • HTTP 401 未经授权

  • 行动后

    如果有效:
  • access_token 和 refresh_token存储在浏览器中(身份验证服务的私有(private)成员变量,浏览器的本地存储)。

  • 看起来存储不是一个好主意refresh_token在本地存储中 - 但这允许“保持登录状态”。如果仅将每个浏览器 session 存储在私有(private)成员变量中,则用户每次打开浏览器时都需要登录。有任何想法吗?

    如果无效:
  • 显示错误,建议重试

  • 2. 浏览器向服务器请求 protected 数据

    要求:
  • 发送 access_token
  • 到/api/resource

  • 回复:
  • 如果 access_token 有效,则发送 json 数据,HTTP 200 OK
  • 如果 access_token 无效(例如无法解码),HTTP 400 错误请求
  • 如果 access_token 过期,HTTP 401 未授权

  • 回应后的行动:
  • 如果 HTTP 200:显示的数据
  • 如果 HTTP 400:重定向到登录页面
  • 如果 HTTP 401:使用存储在浏览器中的 refresh_token 重试获取新的 access_token

  • 3.重试使用refresh_token认证(HTTP 401 Unauthorized后)

    要求:
  • access_token
  • refresh_token

  • 回复:
  • 验证 access_token (除过期时间外的所有内容,使用\Firebase\JWT)
  • 验证 refresh_token针对数据库(从 access_token 解码的 user_id、字符串和到期时间)

  • 如果有效:

    生成新的refresh_token,保存到数据库,更新ttl(或者应该是同一个token,只更新ttl?)
    生成新的 access_token
    HTTP 200 正常

    如果无效:

    HTTP 401 未经授权

    回应后的行动:

    如果有效:
  • 将新的 access_key 和 refresh_key 存储在浏览器中
  • 使用新的 access_key
  • 重试之前的资源请求

    如果无效:
  • 显示登录页面

  • 问题

    我不喜欢的关键点是 access_token 和 refresh_token 存储在同一个地方并以相同的方式发送。也许有另一种方法可以做到?
  • 这个逻辑合理吗?
  • 假设这发生在网络应用程序中,是否存在任何安全漏洞?
  • 我应该将这两个 token 存储在浏览器的本地存储中吗?
  • 应该refresh_token编码为 access_token ?如果它们仍然保存在同一个地方,看起来它可能被合并到access_token中。有什么理由不这样做吗?
  • 我应该什么时候更新 refresh_token生命周期?
  • 任何开源项目都可以看到类似的身份验证?
  • 还有其他建议吗?
  • 最佳答案

    关于在哪里存储 token 和安全漏洞(取自 Github 用户 brettpostin https://github.com/IdentityServer/IdentityServer3/issues/2039#issuecomment-288135399),请记住:

  • 在 localStorage 中存储 token 容易受到 的影响xss .
  • 在 cookie 中存储 token 容易受到 的影响csrf .

  • 最好的选择是防止两者的描述在这里:
    http://www.redotheweb.com/2015/11/09/api-security.html

    将您的 token 存储在 http-only cookie 中并使用合适的目标 csrf 此处建议的防御:
    https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

    when should I update refresh_token lifetime?



    如果您要问 何时更新刷新 token 这取决于您的协议(protocol)的实现,例如 Google Auth 服务器发出的刷新 token 永不过期,当用户撤销对应用程序的访问时,它们将被撤销。但我可以建议几个星期,这样你就不会失去控制。

    any open source projects to see similar authentication in action?



    好吧,你可以下载任何使用 OAuth2 的项目,例如 github 上的这个项目:https://github.com/authlib/example-oauth2-server

    any other suggestions?



    查看 OpenID Connect 和身份提供程序 (IDP),例如 Keycloack。

    希望这可以以任何方式帮助您。

    关于angular - 带有刷新 token 的 JSON Web token 身份验证逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47433907/

    相关文章:

    javascript - 通过 Node-Fetch 检索 OAuth2 token

    ruby-on-rails - 使用 Google Oauth2 客户端访问 API 时 Rails 3.2.3 中的 SSL 错误

    c# - 上传文件报错 415 Unsupported Media Type

    angular - bootstrap 没有连接到 angular 6?

    perl - Mojolicious 应用程序使用谷歌身份验证,插件 OAuth2

    javascript - 检测 iframe 何时跨域,然后清除它

    security - 如果我们在负载均衡器而不是服务器上安装 SSL 证书,是否有任何安全风险?

    javascript - Angular 2 避免编译 CSS 中定义的图像

    angular - 如何使用post请求并传递2个参数在ionic中调用api?

    java - 将 NFC 标签锁定到特定设备?