6

我正在 Symfony2 中构建一个 REST API 应用程序,并试图找到一种处理用户身份验证和授权的好方法。那里有很多解决方案,但到目前为止,它们都没有解决我所有的要求/顾虑。

该 API 将主要由 AngularJS SPA 使用,用户使用用户名和密码组合登录。让 GUI 用户能够:

  • 使用用户名和密码登录
  • 使用“记住我”复选框“永远”登录(可能一周或类似的时间)
  • 同时在不同的浏览器上使用“记住我”(如 facebook)
  • 从浏览器中删除 cookie 以注销用户

在服务器端,我想保持严格的 RESTful。我想出了一个似乎是我需要的解决方案,但我想确保我没有遗漏任何东西。

从服务器的角度来看成功登录尝试的工作流程:

  1. 使用用户名和密码在 /login API 端点上接收 POST
  2. 生成一个新令牌并将其返回给客户端。在 db 中保存该令牌的哈希值。
    • 每个令牌数据库条目必须有一个预定义的生命周期(在配置中设置)
      • 过期日期时间必须存储在数据库中
      • 旧的令牌哈希必须在过期时从数据库中删除(在登录尝试时或通过 cron)
    • 令牌与用户是多对一的——用户可以在任何给定时间拥有多个活动令牌

从服务器的角度来看,登录用户的授权工作流程:

  1. 从授权标头中提取令牌
    • 用户 ID 也可能包含在请求中,待定
  2. 哈希令牌并将其与数据库中每个用户的哈希值进行比较
  3. 如果其中一个 db 哈希与请求哈希匹配并且未过期,则更新哈希过期并授权用户

从客户端 (GUI) 的角度来看,成功登录尝试的工作流程:

  1. 使用用户名和密码向 /login API 端点发送 POST 请求
  2. 接收服务器生成的令牌。存储在浏览器的cookie中(使用js,服务器不设置cookie)

从客户端(GUI)的角度对登录用户进行授权的工作流程:

  1. 从 cookie 中读取 token 并在请求中设置 Authorization 标头,例如 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
    • 始终从 cookie 中读取令牌,因为用户可能希望删除它以在浏览器中注销自己。

如果登录失败(cookie 被删除或 401 响应)丢弃所有表单数据,删除 cookie 并重定向到登录屏幕。

显然,存储在客户端的 cookie 将在每次请求时传递给服务器,因为这就是 cookie 的作用,但服务器会忽略它。cookie 仅供客户端使用。增加的带宽开销被认为可以忽略不计。

这个工作流程看起来好吗?我错过了什么吗?

4

1 回答 1

1

我已经完成了一个名为WebApiSecure的项目,它使用Json Web Tokens(JWT)进行授权 - BasicBearer。我相信它可以完成您描述的大部分事情,例如允许令牌过期和添加用户 ID 或角色。它可能会帮助您完成您想做的事情。

它是使用 Web Api 2 构建的,前端可以基于 AngularJS 或 JQuery。

于 2015-02-02T14:46:39.067 回答