我正在对用户进行身份验证以使用我自己的API(因此是受信任的来源).我正在努力确定的是在客户端存储返回access_token的最佳位置在哪里?我是否创建cookie,或将数据保存在localstorage中?
我也应该只存储access_token,我应该记录refresh_token吗?什么是刷新令牌?
最佳答案 如果您只在客户端存储访问令牌更安全,即使您的刷新令牌在一段时间后过期,尽管这样做会减少可能的攻击窗口.
这是一种方法(如果你想存储访问和刷新令牌):
https://stackoverflow.com/a/18392908/5549377
然而,还有另一种方法.
通过这种方式,客户端将只获取访问令牌,并且刷新令牌完全对用户隐藏.但为了做到这一点,访问令牌以及刷新令牌应该存储在服务器端.最好的地方是在数据库中.这提出了一个显而易见的问题:安全性?那么答案就是你总是可以加密存储在数据库中的数据并尽可能保护你的数据库.
>创建一个表(user_token表),可以存储user_id,访问令牌,refresh_token甚至session_id.
>在每次登录时检查user_token表中user_id下是否存在记录.如果它不存在,请请求oauth / token并将访问和刷新令牌存储在user_token表中.
>登录成功后,您可以在角度中编写.run函数,以请求用户访问令牌. (记住在user_token表中我们有一个“user_id”列.因此,您可以请求从laravel中的Auth :: id()函数过滤当前登录的用户.
>找到访问令牌后,服务器应仅将访问令牌和访问令牌返回给客户端.
>客户端收到访问令牌后,您可以对“middleware”=>下受保护的路由进行握手调用. ‘auth:api’通过将收到的access_token添加到标题中,如下所示:$http.defaults.headers.common.Authorization =’Bearer’data.access_token;.在这样做之后,请确保将相同的标记添加到一个rootscope变量,如下所示:$rootScope.accesstoken = data.access_token;
>如果握手调用成功,那么您可以将有效的访问令牌从rootscope添加到角度cookie,如下所示:$cookies.put(‘access_token’,$rootScope.accesstoken);
>如果握手呼叫不成功,您可以请求新令牌.要请求新令牌,请使用将重定向到单独功能的新路由.此函数将获取当前用户的user_id下的刷新令牌,并从oAuth端点请求新的访问令牌(请参阅Passport API文档).执行此操作后,在“user_tokens”表中更新用户下的记录,并将新的访问令牌返回给Web客户端.在webclient端,将收到的令牌存储在角度cookie中,如下所示:$cookies.put(‘access_token’,$rootScope.accesstoken);并将相同的标记添加到http标题中:$http.defaults.headers.common.Authorization =’Bearer’data.access_token;
顺便说一下,为什么我提到我应该将令牌存储在角度cookie中.好吧,如果你只在rootcope上存储它,如果页面刷新,应用程序将不得不再次请求一个令牌,因为角度rootcope中的任何数据在刷新后都会丢失.但在角饼干中,它不是.因此这就是我建议添加角饼干的原因.
很重要:
对于您发出的每个ajax请求,如果请求在代码401(未授权访问)下失败,您应该从angular调用请求新令牌函数到Laravel的请求新令牌函数.一旦成功,就像我提到的那样将新令牌插入http头和角度cookie.
注意:
刷新令牌的目的是验证您是旧访问令牌的经过身份验证的用户(让我们调用令牌xxx).
只要到期,您就可以使用访问令牌.一旦它确实你需要告诉服务器你不能使用这个access_token xxx并且它现在已经过期,所以给我一个新的令牌.当您提出此请求(为您提供新令牌)时,服务器应该知道您是先前访问令牌的合法用户,因此服务器会要求您证明您是合法的.那时,您可以呈现刷新令牌并证明服务器您是合法的.这是刷新令牌的使用.
那么服务器将如何通过刷新令牌验证您是否合法?
最初,当您请求访问令牌时,您将获得刷新令牌,因此在这种情况下服务器将知道.
我建议您阅读并了解有关OAuth 2.0的更多信息.