4

我正在对用户进行身份验证以使用我自己的 API(因此是受信任的来源)。我正在努力确定的是在客户端存储返回 access_token 的最佳位置在哪里?我是创建一个 cookie,还是将数据保存在本地存储中?

我也应该只存储access_token,我应该记录refresh_token吗?刷新令牌的用途是什么?

4

2 回答 2

2

即使您的刷新令牌在一段时间后过期,如果您只将访问令牌存储在客户端会更安全,尽管这样做会减少可能的攻击窗口。

这是一种方法(如果您想存储访问和刷新令牌):

https://stackoverflow.com/a/18392908/5549377

但是,还有另一种方法。这样,客户端只会获得访问令牌,而刷新令牌对用户是完全隐藏的。但为了做到这一点,访问令牌和刷新令牌应该存储在服务器端。最好的地方是在数据库中。这就提出了一个显而易见的问题:安全性?那么答案是您始终可以加密存储在数据库中的数据并尽可能保护您的数据库。

  1. 创建一个表(user_token 表),可以存储 user_id、access token、refresh_token 甚至 session_id。
  2. 在每次登录时,检查 user_token 表中的 user_id 下是否存在记录。如果不存在,则请求oauth/token并将访问和刷新令牌存储在 user_token 表中。
  3. 登录成功后,您可以在 Angular 中编写一个 .run 函数来为用户请求访问令牌。Auth::id()(请记住,在 user_token 表中,我们有一个“user_id”列。因此,您可以请求从laravel 中的函数过滤当前登录的用户。
  4. 一旦找到访问令牌,服务器应该只将访问令牌和访问令牌返回给客户端。
  5. 客户端收到访问令牌后,您可以'middleware' => 'auth:api'通过将收到的 access_token 添加到标头中来对受保护的路由进行握手调用,如下所示:$http.defaults.headers.common.Authorization = 'Bearer ' + data.access_token;。同样在这样做之后,请确保将相同的标记添加到 rootscope 变量中,如下所示:$rootScope.accesstoken = data.access_token;
  6. 如果握手调用成功,那么您可以将有效访问令牌从 rootscope 添加到 angular cookie,如下所示:$cookies.put('access_token', $rootScope.accesstoken);
  7. 如果握手调用不成功,您可以请求一个新的令牌。要请求新令牌,请使用将重定向到单独函数的新路由。此函数将获取当前用户的 user_id 下的刷新令牌,并从 oAuth 端点请求新的访问令牌(请参阅 Passport API 文档)。执行此操作后,更新“user_tokens”表中用户下的记录,并将新的访问令牌返回给 Web 客户端。在 webclient 端,将收到的令牌存储在 angular cookie 中,如下所示:$cookies.put('access_token', $rootScope.accesstoken);并将相同的令牌添加到 http 标头中,如下所示:$http.defaults.headers.common.Authorization = 'Bearer ' + data.access_token;

顺便说一句,为什么我提到我应该将令牌存储在 angular cookie 中。好吧,如果您仅将其存储在rootscope,如果页面刷新,则应用程序将不得不再次请求令牌,因为无论角度根范围中的数据在刷新后都会丢失。但在角饼干中,它不是。因此这就是为什么我建议添加到 angular cookie 中。

很重要:

对于您发出的每个 ajax 请求,如果请求在代码 401(未经授权的访问)下失败,您应该从 angular 调用请求新令牌函数到 Laravel 的请求新令牌函数。成功后,将新令牌插入到我提到的 http 标头和 angular cookie 中。

笔记:

刷新令牌的目的是验证您是否是旧访问令牌的经过身份验证的用户(我们称之为令牌xxx)。

只要访问令牌过期,您就可以使用它。一旦完成,你需要告诉服务器你不能使用这个 access_token xxx,它现在已经过期了,所以给我一个新的令牌。当你发出这个请求(给你一个新的令牌)时,服务器应该知道你是前一个访问令牌的合法用户,所以服务器会要求你证明你是合法的。届时,您可以出示刷新令牌并证明您是合法的服务器。这是刷新令牌的使用。

那么服务器如何通过刷新令牌验证你是合法的呢?最初,当您请求访问令牌时,您会获得刷新令牌,因此在这种情况下服务器会知道。

我建议您阅读并了解有关 OAuth 2.0 的更多信息。

于 2016-11-18T12:33:32.760 回答
0

我最近浏览了一些用于令牌存储的客户端选项,因此我将向您推荐以下提供的答案:在基于浏览器的应用程序中保存 JWT 的位置。

长话短说,cookie 和 Web 存储都是存储访问令牌的合适选项,正确的选择取决于您的具体情况。

关于您应该存储的内容,它通常只是访问令牌,主要是因为刷新令牌通常不会颁发给基于浏览器的应用程序,因为它们是长期存在的凭据,这意味着试图窃取它们的人的可用时间会大大增加,并且浏览器存储选项都有其不足之处。

当客户端应用程序想要访问最终用户拥有的受保护资源时,即使用户没有与应用程序交互,刷新令牌也特别重要;通常称为离线访问。基于浏览器的应用程序的大多数场景仍然暗示用户在线,因此缺少刷新令牌并不是什么大问题。

于 2016-11-09T09:48:13.100 回答