需求:前后端分离状态下,登录失效(token过期)后,前端需要知道下一步是跳转到登录页面还是使用refresh_token刷新token。

这就需要后端根据是否可以刷新token(refresh_token是否过期)返回不同的标识,以供前端进行下一步操作。

具体做法如下:

1、新建RefreshToken中间件,每次登陆成功后查询是否保存了token和id的对应关系(登录失效后无法通过token获取对应id)

<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
use Illuminate\Support\Facades\DB;
class RefreshToken
     * @param $request
     * @param Closure $next
     * @return mixed
    public function handle($request, Closure $next)
        $token=$request->header('authorization');
        $has=DB::table('oauth_refresh_tokens_ids')->where('access_token',$token)->value('access_token_id');
        if(!$has){
            DB::table('oauth_refresh_tokens_ids')->insert(['access_token'=>$token,'access_token_id'=>Auth::user()->token()->id]);
        return $next($request);
View Code

2、kerne.php文件内为RefreshToken中间件分配一个key

protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,       
        'refresh'=>\App\Http\Middleware\RefreshToken::class,//刷新token
View Code

3、在路由中使用RefreshToken中间件

4、重写Authenticate中间件登录失效后的跳转方法redirectTo

protected function redirectTo($request)
        $token=$_SERVER['HTTP_AUTHORIZATION'];
        $accessTokenId=DB::table('oauth_refresh_tokens_ids')->where('access_token',$token)->value('access_token_id');
        $RefreshTokensExpiresAt=DB::table('oauth_refresh_tokens')->where('access_token_id',$accessTokenId)->value('expires_at');
        if(strtotime($RefreshTokensExpiresAt)>strtotime(now())){
            //可刷新token
            return route('login',['code'=>402]);
        }else{
            return route('login',['code'=>401]);
View Code

5、新建路由

Route::get('login/{code}', function ($code) {
    return response()->json(['code'=>$code,'msg'=>'login timeout.']);
})->name('login');
View Code

1、登录超时后refresh_token未过期时返回

"code": "402", "msg": "login timeout."

2、登录超时后refresh_token过期时返回

"code": "401", "msg": "login timeout."

说明:虽然数据表中存了token和refresh_token的创建时间和失效时间,但是框架验证的时候并没有从数据表中取值,而是直接通过token计算出来,不得不说安全性是真的高。所以通过修改token过期时间来进行登录状态续期的办法不可行,必须对token进行刷新。

Enjoy it !