【问题标题】:Tymon JWT Laravel Vue refresh token stored in localstorageTymon JWT Laravel Vue 刷新令牌存储在本地存储中
【发布时间】:2018-04-01 03:59:46
【问题描述】:

所以我开始为我的 SPA 使用 Laravel 的 Tymon JWT 包。一切顺利(添加用户、登录、获取 Auth 用户),但是当我发出 API 请求时,它只能工作一个小时。我了解我在登录时存储的令牌已过期,因此当我在 60 分钟后向 API 发出请求时,它不起作用。我的问题是如何刷新令牌并将其恢复到本地存储中?在一个新的请求?每 59 分钟一次?

AuthController.php

    public function authenticate(Request $request)
    {
        // grab credentials from the request
        $credentials = $request->only('email', 'password');

        try {
            // attempt to verify the credentials and create a token for the user
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(['error' => 'Sorry, we cant find you.']);
            }
        } catch (JWTException $e) {
            // something went wrong whilst attempting to encode the token
            return response()->json(['error' => 'could_not_create_token'], 500);
        }

        // all good so return the token
        $user = JWTAuth::toUser($token);

        //Fire off the login event
        event( new LoginSuccessful($user) );

        return response()->json( compact('token', 'user') );
    }

登录.vue

            axios.post('/api/authenticate',{
                email: this.email,
                password: this.password
            })
            .then(response => {

                if(response.data.error){

                    //Show the error
                    this.error = response.data.error
                    this.loading = false;

                } else {

                    this.loading = false;

                    //Store the items in storage
                    localStorage.setItem('jwt_token', response.data.token);
                    localStorage.setItem('user', JSON.stringify(response.data.user));

                    //Mutate the state
                    this.$store.commit('login');

                    //Now go to the dashboard
                    this.$router.push('dashboard');
                }

            })
            .catch(error => {

            });

在我的头标签中

<script>

    window.hopbak = {
        'jwt_token': localStorage.getItem('jwt_token'),
        'csrfToken': {!! json_encode( csrf_token() ) !!},
    };

</script>

在我的 bootstrap.js 中

let token = window.hopbak.jwt_token;

if (token) {

    window.axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;

} else {
    console.log('no token');
}

【问题讨论】:

  • 这是高级别的,没有任何代码可以提供帮助,但是当您收到 API 令牌返回时,我会将其与刷新令牌一起存储在本地存储中。然后,当您进行 API 调用时,添加一个 catch 以检查错误是否与 API 令牌已过期有关,如果确实如此,则使用刷新令牌获取新的 API 令牌,然后自动重试原始请求。

标签: laravel vue.js jwt


【解决方案1】:

JWT_TTLJWT_REFRESH_TTLJWT_BLACKLIST_GRACE_PERIOD 值在 config/jwt.php 文件中设置。

它是如何工作的:

  1. 客户端将凭据(电子邮件和密码)发送到 Laravel 并 接收令牌(JWT)作为响应。此令牌对 JWT_TTL 有效 分钟。在此期间,所有带有 Authorization 标头的请求 = "Bearer token" 会成功。
  2. 对于JWT_TTL分钟之后的请求,即令牌过期,会出现两种情况:(1)如果令牌创建后的时间少于JWT_REFRESH_TTL分钟(令牌在其中包含声明 IAT 的创建日期),则此令牌将无效(黑名单),并且将生成一个新令牌并将其作为响应发送给客户端。 JWT_REFRESH_TTL 定义在创建第一个令牌后多少分钟可以创建新令牌。例如,对于 JWT_REFRESH_TTL = 21600,新令牌将生成 15 天,之后用户应重新进行身份验证。 (2) 在创建第一个令牌后的 JWT_REFRESH_TTL 分钟后发出请求。在这种情况下,将无法为客户端生成新令牌,并且必须再次进行身份验证。将向客户端发送 401 错误。
  3. 当使用同一个 JWT 发出多个并发请求时, 由于令牌重新生成,其中一些可能会失败 每个请求。以秒为单位设置宽限期以防止并行 请求失败,因为 JWT 会认为对 JWT_BLACKLIST_GRACE_PERIOD 秒,即使它在黑名单上。

更多详情请见this my explanation

【讨论】:

    【解决方案2】:

    我觉得你需要在app/Http/Kernel.php注册RefreshToken中间件:

    protected $routeMiddleware = [
        'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken'
    ];
    

    然后将其分配给要刷新令牌的路由。

    查看source code,我可以看出该中间件将通过向响应标头添加新令牌来处理每个请求中令牌的刷新。

    【讨论】:

    • 每次登录都很好并且应用程序正常工作时,我都会返回一个新令牌,但只能使用一个小时。所以我需要每 60 分钟获取一次刷新令牌,而不仅仅是在登录时出现
    • 没试过但是看源代码我想你只需要在你的路由中添加RefreshToken中间件。
    猜你喜欢
    • 2019-05-06
    • 1970-01-01
    • 2018-10-21
    • 2019-03-23
    • 2020-10-25
    • 2018-11-12
    • 2022-01-15
    • 2018-11-15
    • 1970-01-01
    相关资源
    最近更新 更多