我正在Symfony2中构建一个REST API应用程序,我正在尝试找到一种处理用户身份验证和授权的好方法.有很多解决方案,但到目前为止,它们都没有满足我的所有要求/关注.
该API主要由AngularJS SPA使用,用户使用用户名和密码组合登录.让GUI用户能够:
- 使用用户名和密码登录
- 使用"记住我"复选框登录"永远"(可能一周或类似的东西)
- 同时在不同浏览器中使用"记住我"(如facebook)
- 从浏览器中删除cookie以将用户注销
在服务器端,我希望保持严格的RESTful.我提出了一个似乎是我需要的解决方案,但我想确定我没有遗漏任何东西.
从服务器的角度成功登录尝试的工作流程:
- 使用用户名和密码在/ login API端点上接收POST
- 生成新令牌并将其返回给客户端.在db中保存该标记的哈希值.
- 每个令牌数据库条目必须具有预定义的生存期(在配置中设置)
- 到期日期时间必须存储在db中
- 必须在db到期时(在登录尝试时或通过cron)从db中删除旧的令牌哈希值
- 令牌与用户是多对一的 - 用户可以在任何给定时间拥有多个活动令牌
从服务器的角度来看授权登录用户的工作流程:
- 从Authorization标头中提取令牌
- 散列令牌并将其与db中每个用户的散列进行比较
- 如果其中一个db哈希与请求哈希匹配且未过期,则更新哈希过期并授权用户
从客户端(GUI)角度尝试成功登录的工作流程:
- 使用用户名和密码将POST请求发送到/ login API端点
- 接收服务器生成的令牌.将其存储在浏览器中的cookie中(使用js,服务器不设置cookie)
从客户端(GUI)角度授权登录用户的工作流程:
- 从cookie中读取令牌并在请求中设置授权头,例如授权:基本QWxhZGRpbjpvcGVuIHNlc2FtZQ ==
- 总是从cookie中读取令牌,因为用户可能想要删除它以在浏览器中登出.
如果登录失败(cookie已删除或401响应)丢弃所有表单数据,请删除cookie并重定向到登录屏幕.
显然,存储在客户端的cookie将在每次请求时传递给服务器,因为这就是cookie所做的事情,但服务器会忽略它.cookie仅供客户使用.增加的带宽开销被认为可以忽略不计.
这个工作流程看起来好吗?我错过了什么吗?