王剑编程网

分享专业编程知识与实战技巧

【PHP】Laravel JWT完整使用教程_laravel jwt token验证

一、JWT 简单介绍

JWT 全称 JSON Web Tokens ,是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。它的两大使用场景是:认证和数据交换。

以下步骤都是经过本人自研项目实践过,大家可以放心参考;

二、安装之前

主要使用的扩展及参考资料:

  • PHP-Open-Source-Saver/jwt-auth
  • JWT 完整使用详解
  • JWT的介绍
  • 官方安装指导文件

三、安装及配置

1)使用 composer 安装

composer require php-open-source-saver/jwt-auth

2)进行一些配置

2.1)发布配置文件

这条命令会在 config 下增加一个 jwt.php 的配置文件

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

2.2)生成加密密钥

这条命令会在 .env 文件下生成一个加密密钥,如:JWT_SECRET=foobar

php artisan jwt:secret

2.3)生成证书(可选)

这一步可不配置,但配置后生成的 Token 会根据证书文件来生成,更加安全;详细可看官方安装指导里的说明。

php artisan jwt:generate-certs

2.4)更新你的模型

如果你使用默认的 User 表来生成 Token,你需要在该模型下增加一段代码
app/Models/User.php


getKey();
    }

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

2.5)注册两个 Facade

这两个 Facade 并不是必须的,但是使用它们会给你的代码编写带来一点便利。
config/app.php


'aliases' => [
        ...
        // 添加以下两行
        'JWTAuth' => 'Tymon\JWTAuth\Facades\JWTAuth',
        'JWTFactory' => 'Tymon\JWTAuth\Facades\JWTFactory',
],

如果你不使用这两个 Facade,你可以使用辅助函数 auth ()
auth () 是一个辅助函数,返回一个 guard,暂时可以看成 Auth Facade。


// 如果你不用 Facade,你可以这么写
auth('api')->refresh();
// 用 JWTAuth Facade
JWTAuth::parseToken()->refresh();

两个 Facede 常用可使用方法,可以看文章后面的附录。

2.6)修改 auth.php

config/auth.php


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

    'api' => [
        'driver' => 'jwt',        // 原来是 token 改成jwt
        'provider' => 'users',
    ],
],

2.7)创建 Auth 控制器

php artisan make:controller AuthController

app/Http/Controllers/AuthController.php

值得注意的是 Laravel 这要用 auth('api')。


middleware('jwt.auth', ['except' => ['login']]);
          // 另外关于上面的中间件,官方文档写的是『auth:api』
          // 但是我推荐用 『jwt.auth』,效果是一样的,但是有更加丰富的报错信息返回
    }

    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login()
    {
        $credentials = request(['email', 'password']);

        if (! $token = auth('api')->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }

        return $this->respondWithToken($token);
    }

    /**
     * Get the authenticated User.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json(auth('api')->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth('api')->logout();

        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     * 刷新token,如果开启黑名单,以前的token便会失效。
     * 值得注意的是用上面的getToken再获取一次Token并不算做刷新,两次获得的Token是并行的,即两个都可用。
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth('api')->refresh());
    }

    /**
     * Get the token array structure.
     *
     * @param  string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth('api')->factory()->getTTL() * 60
        ]);
    }
}

四、JWT Token 详解

1)Token 创建

前面的 AuthController.php 中有两行展现了这一种 Token 的创建方法,即用用户所给的账号和密码进行尝试,密码正确则用对应的 User 信息返回一个 Token 。

但 Token 的创建方法不止这一种,接下来介绍 Token 的三种创建方法:

  • 基于账密参数
  • 基于 users 模型返回的实例
  • 基于 users 模型中的用户主键 id

a)基于账密参数

这就是刚刚说的哪一种,贴出具体代码。


// 使用辅助函数
$credentials = request(['email', 'password']); 
$token = auth()->attempt($credentials)

// 使用 Facade
$credentials = $request->only('email', 'password');
$token = JWTAuth::attempt($credentials);

b)基于 users 模型返回的实例


// 使用辅助函数
$user = User::first();
$token = auth()->login($user);

// 使用 Facade
$user = User::first();
$token = JWTAuth::fromUser($credentials);

c)基于 users 模型中的主键 id


// 使用辅助函数
$token = auth()->tokenById(1);

// 使用 Facade
源码中没找到

2)Token 的解析

a)解析 Token 到对象

只有 Facade 需要这样。


// 把请求发送过来的直接解析到对象
JWTAuth::parseToken();

b)获取 Token 中的 user 信息


// 辅助函数
$user = auth()->user();

// Facade
$user = JWTAuth::parseToken()->authenticate();

c)获取 Token

如果 token 被设置则会返回,否则会尝试使用方法从请求中解析 token ,如果 token 未被设置或不能解析最终返回 false。


// 辅助函数
$token = auth()->getToken();

// Facade
$token = JWTAuth::parseToken()->getToken();

更多方法可以看官方安装指南文件。

五、Token 的三个时间

一个 Token 一般来说有三个时间属性,其配置都在 config/jwt.php 内。

有效时间

有效时间指的的是你获得 Token 后,在多少时间内可以凭这个 Token 去获取内容,逾时无效。


// 单位:分钟
'ttl' => env('JWT_TTL', 60)

刷新时间

刷新时间指的是在这个时间内可以凭旧 Token 换取一个新 Token。例如 Token 有效时间为 60 分钟,刷新时间为 20160 分钟,在 60 分钟内可以通过这个 Token 获取新 Token,但是超过 60 分钟是不可以的,然后你可以一直循环获取,直到总时间超过 20160 分钟,不能再获取。


// 单位:分钟
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160)

宽限时间

宽限时间是为了解决并发请求的问题,假如宽限时间为 0s ,那么在新旧 token 交接的时候,并发请求就会出错,所以需要设定一个宽限时间,在宽限时间内,旧 Token 仍然能够正常使用。


// 宽限时间需要开启黑名单(默认是开启的),黑名单保证过期token不可再用,最好打开
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true)

// 设定宽限时间,单位:秒
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 60)
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言