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_tokenaccess_token 编码?如果它们仍保存在同一个地方,则可以将其合并到access_token中 . 有什么理由不去做吗?

  • 什么时候应该更新 refresh_token 生命周期?

  • 任何开源项目看到类似的身份验证在行动?

  • 还有其他建议吗?