JWT/LARAVEL令牌已过期 [英] JWT/LARAVEL token expired

查看:851
本文介绍了JWT/LARAVEL令牌已过期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个API,但令牌过期有问题,我试图找到刷新API发送的令牌的方法,但没有发现任何问题 这是我的用户mdoal:

I developed an API and I have a problem with the expiration of the token, and I try to find ways to refresh the tokens sent by API and I found nothing This is my user mdoal:

<?php

namespace App;


use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password','username','lastname','tel','tel',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }
}

这是我的loginController

and this is my loginController

<?php

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
use App\User;
use JWTFactory;
use JWTAuth;
use Validator;


class APILoginController extends Controller
{
    //


    public function login( Request $request){
        $validator = Validator::make($request -> all(),[
         'email' => 'required|string|email|max:255',
         'password'=> 'required'
        ]);

        if ($validator -> fails()) {
            # code...
            return response()->json($validator->errors());

        }


        $credentials = $request->all('email','password');
        try{
            if (! $token = JWTAuth::attempt( $credentials) ) {
                # code...
                return response()->json( ['error'=> 'invalid username and password'],401);
            }
        }catch(JWTException $e){

          return response()->json( ['error'=> 'could not create token'],500);
        }

        $currentUser = Auth::user();

        return response()->json( ['user'=> $currentUser,'token'=>compact('token')],200);
        ///return response()->json( compact('token'));

    }

}

我在github中找到了创建自定义中间件的解决方案,当令牌过期时,刷新的令牌将添加到响应头中.该应用仅需要搜索响应中是否包含此内容,如果是,则更新保存的令牌.

and I found in github a solution to creat a custom middleware,When the token is expired, the refreshed token is added to the response headers. The app just needs to search if the response has this, if so, update the saved token.

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        try
        {
            if (! $user = JWTAuth::parseToken()->authenticate() )
            {
                return response()->json([
                    'code'   => 101, // means auth error in the api,
                   'response' => null // nothing to show
                 ]);
            }
        }
        catch (TokenExpiredException $e)
        {
            // If the token is expired, then it will be refreshed and added to the headers
            try
            {
                $refreshed = JWTAuth::refresh(JWTAuth::getToken());
                $user = JWTAuth::setToken($refreshed)->toUser();
                header('Authorization: Bearer ' . $refreshed);
            }
            catch (JWTException $e)
            {
                return response()->json([
                    'code'   => 103, // means not refreshable
                   'response' => null // nothing to show
                 ]);
            }
        }
        catch (JWTException $e)
        {
            return response()->json([
                'code'   => 101 ,//, means auth error in the api,
                   'response' => null // nothing to show
            ]);
        }

        // Login the user instance for global usage
        Auth::login($user, false);

        return  $next($request);
    }
}

推荐答案

因此,您正在使用普通的PHP方法在Laravel中间件中设置标头,这将无法正常工作.

So you are using normal PHP methods for setting headers inside a Laravel middleware, that ain't going to work.

您应该检查以下内容: https://github.com/tymondesigns/jwt-auth/blob/develop/src/Http/Middleware/BaseMiddleware.php

You should checko this out: https://github.com/tymondesigns/jwt-auth/blob/develop/src/Http/Middleware/BaseMiddleware.php

https://github.com /tymondesigns/jwt-auth/blob/develop/src/Http/Middleware/RefreshToken.php

基本上,更改:

header('Authorization: Bearer ' . $refreshed);

$response = $next($request);
$response->headers->set('Authorization', 'Bearer '.$token);

以下是问题,此方法无法按预期进行,因为这种"AfterMiddleware"是在请求通过您的应用程序后执行的.所以:

The thing is the following, this aproach won't work as expected because this kind of "AfterMiddleware" gets executed after the request has been throught your app. So:

  1. 用户使用过期的令牌发出请求
  2. 由于TokenExpired,应用程序将返回403或401(不记得了).
  3. 不过,响应中将包含带有新令牌的标头
  4. 您使用新令牌提出了相同的请求,它应该可以正常工作.

这篇关于JWT/LARAVEL令牌已过期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆