Angular 4应用程序在浏览器(网站后端)中运行,显示来自特定用户拥有的服务器数据 . 服务器:PHP MySQL,Zend Framework 3 Doctrine ORM
命名:
-
access_token
:短寿命(1分钟),允许访问个人资源,携带user_id,base64编码,json web令牌规范有效 . -
refresh_token
:长寿命(1周)允许检索新的access_token而不提供存储在db中的凭据,如果需要,可以由管理员撤销 .
使用refresh_tokens的主要目的是记录超过 access_token
短生命周期(如果在每次用户授权发生时更新 refresh_token
到期时间,可能永远记录),用户只有在不活动超过 refresh_token
生存期的情况下才需要提供凭据 . 刷新令牌存储在db中,因此可以轻松撤销 .
1.浏览器尝试进行身份验证
请求:
-
用户名和密码
-
发送到/ api / auth
响应:
验证用户名和密码并根据数据库进行检查
如果有效:
生成
-
access_token
,到期时间为60秒 -
user_id
被编码为access_token
生成 -
refresh_token
(随机字符串)并保存到db,到期时间为1周,(refresh_token不包含在access_token中,它是一个单独的键) -
HTTP 200 OK
如果无效:
- HTTP 401未经授权
之后的行动
如果有效:
存储在浏览器中的
- access_token和
refresh_token
(auth服务的私有成员varialbe,浏览器的本地存储) .
看起来将 refresh_token
存储在本地存储中不是一个好主意 - 但这允许"keep me signed in" . 如果仅在私有成员变量中按浏览器会话存储,则用户每次打开浏览器时都需要登录 . 有任何想法吗?
如果无效:
- 显示错误,建议重试
2.浏览器向服务器请求受保护的数据
请求:
-
发送access_token
-
到/ api /资源
响应:
-
如果access_token有效,则发送json数据,HTTP 200 OK
-
如果access_token无效(例如,无法解码),HTTP 400 Bad Request
-
如果access_token已过期,则HTTP 401未经授权
回复后的行动:
-
如果HTTP 200:显示数据
-
如果HTTP 400:重定向到登录页面
-
如果HTTP 401:使用存储在浏览器中的refresh_token重试获取新的access_token
3.使用refresh_token重试进行autenticate(在HTTP 401 Unauthorized之后)
请求:
-
access_token
-
refresh_token
响应:
-
验证
access_token
(除了到期时间之外的所有内容,使用\ Firebase \ JWT) -
针对数据库验证
refresh_token
(user_id从access_token解码,字符串和到期时间)
如果有效:
生成新的refresh_token,保存到数据库,更新ttl(或者应该是同一个令牌,只更新ttl?)生成新的access_token HTTP 200 OK
如果无效:
HTTP 401未经授权
回复后的行动:
如果有效:
-
在浏览器中存储新的access_key和refresh_key
-
使用新的access_key重试先前的资源请求
如果无效:
- 显示登录页面
问题
我不喜欢的关键点是access_token和refresh_token存储在同一个地方并以相同的方式发送 . 也许有另一种方法可以做到这一点?
-
这个逻辑是否明智?
-
是否有任何安全漏洞,假设这种情况发生在网络应用程序中?
-
我应该将这两个令牌存储在浏览器的本地存储中吗?
-
应
refresh_token
在access_token
编码?如果它们仍保存在同一个地方,则可以将其合并到access_token中 . 有什么理由不去做吗? -
什么时候应该更新
refresh_token
生命周期? -
任何开源项目看到类似的身份验证在行动?
-
还有其他建议吗?