laiyuquan

博客

JWT -- 理论介绍、实战、问题QA(2)

本篇用laravel 进行jwt的实际运用:

下载安装:

composer require tymon/jwt-auth

增加配置(laravel5.4及以下)

config/app.php 增加注册服务

'providers' => [
      ...
      Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]

新增配置文件:
新增配置文件 config/jwt.php,对包进行基本配置

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

生成密钥:

php artisan jwt:secret

然后再.env 文件 JWT_SECRET = you generate secret key

这个key 就是 jwt的私钥


具体使用:

设置模型类:

namespace App\Models;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class UserModel extends Authenticatable implements JWTSubject
{
    use Notifiable;

    // Rest omitted for brevity

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    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 [];
    }
}

配置AUTH

config/auth.php需要改变providers的配置

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt', #将token驱动变为jwt
        'provider' => 'users',
    ],
],
'providers' => [
      'users' => [
      'driver' => 'eloquent',
      'model' => App\Models\UserModel::class, #自己配置UserModel
 ],

      // 'users' => [
      // 'driver' => 'database',
      // 'table' => 'clg_users',
      // ],
 ],

这样基本的配置就OK了,接下去就具体进行使用;


创建jwtToken

public static function genearte(){

   //创建的新的token
   $user = UserModel::where('id', 1)->first();
   $token = JWTAuth::fromUser($user);
}

验证JwtToken (最好放入中间件)

public function handle($request, Closure $next)
{
    try {
         global jwtUser;

        if(!$jwtUser = JWTAuth::parseToken()->authenticate()) {

            return response()->json(
                [
                    'error' => true,
                    'code' => 10000,
                    'msg' => '该认证token的用户不存在!'  //user_id  进行了删除
                ]
            );
        }
    } catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
        return response()->json(
            [
                'error' => true,
                'code' => 10001,
                'msg' => 'token认证过期,请重新登录!' //认证过期
            ]
        );
    } catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
        return response()->json(
            [
                'error' => true,
                'code' => 10002,
                'msg' => '无效的token!' //ok 任意更改
            ]
        );
    } catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
        return response()->json(
            [
                'error' => true,
                'code' => 10003,
                'msg' => '认证token不存在!' //没有传递token
            ]
        );
    }

    #下面程序的设计是:token有效期在3分钟以内,产生新的jwtToken;
    #然后前端重新保存。目的是延长有效期,对于用户是无感知的。
    $res = JWTAuth::payload();
     
    global jwtToken;    

    if( ($res['exp'] - time()) < 180){  //三分钟

        $jwtToken = JWTAuth::parseToken()->refresh();

    }else{

        $requestToken = $request->header('authorization');

        preg_match('/Bearer\s(\S+)/', $requestToken, $matches);

        $jwtToken = ($matches[1]);

    }

    return $next($request);

}

两个全局变量:

  1. jwtUser      后面的程序 通过这个变量 拿到相应用户数据;
  2. jwtToken   后面的程序 返回接口时 都将JwtToken返回给前端;

 

刷新jwtToken

//刷新token 旧的token 会自动失效
public static function refresh(){

    try{

        $res = JWTAuth::parseToken()->check();

        if($res === false){
            return response()->json(
                [
                    'error' => true,
                    'code' => 10003,
                    'msg' => 'token无效!'
                ]
            );
        }

    }catch (\Tymon\JWTAuth\Exceptions\JWTException $e){
        return response()->json(
            [
                'error' => true,
                'code' => 10003,
                'msg' => '认证token不存在!' //没有传递token
            ]
        );
    }

    //产生新的token
    $newToken = JWTAuth::parseToken()->refresh();

}

改方法 常用于: 用户注销、更改密码;

 

使jwtToken无效

public static function invalidate(){
    
    $res = JWTAuth::parseToken()->invalidate();

    dump($res);
    
}


使用还是非常清晰的,建议将config/jwt.php下的配置好好看一下

jwt 关键是 理解它的原理,使用场景 和 使用过程中 可能出现的一些问题;

学习资料:

官方文档:https://jwt.io/introduction/

laravel jwt类包文档:http://jwt-auth.readthedocs.io/en/develop/

jwt git地址:https://github.com/tymondesigns/jwt-auth

 

点赞

发表评论