laravel5.5(Jwt-auth)的使用

前言:当某个项目需要前后端分离开发时,考虑到用户认证体系时,就可以使用jwt-auth认证。

目录

一、jwt-auth的安装与配置

1. 使用 composer 安装 jwt-auth

2.发布配置文件 和 生成秘钥

3. 更新需要Token认证的模型 

4. 注册两个 Facade (config/app.php)

5. 修改 auth.php 

6. 注册路由(测试jwt-auth功能)

 7. 创建 token 控制器(测试jwt-auth功能)

二、JWT Token 详解

1. token 的获取、使用、删除和刷新

2. token 的创建

3. token 的解析

4. token 的三个时间

三、附录

1. JWT 的 两个 Facade

1.1 JWTAuth


一、jwt-auth的安装与配置

1. 使用 composer 安装 jwt-auth

# 建议使用1.0以上版本
composer require tymon/jwt-auth 1.*@rc
  1. 这里值得注意的是,有些文档会说要添加 Tymon\JWTAuth\Providers\LaravelServiceProvider::class ,这只在 Laravel 5.4 及以下版本是必要的,更新的 Laravel 版本无需添加。
  2. 还有一些文档说要添加 Tymon\JWTAuth\Providers\JWTAuthServiceProvider 这是很久以前的 JWT 版本的(大概 0.5.3 以前的版本)。

2.发布配置文件 和 生成秘钥

# 这条命令会在 config 下增加一个 jwt.php 的配置文件
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

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

3. 更新需要Token认证的模型 

如果你使用默认的 User 表来生成 token,你需要在该模型下增加一段代码

4. 注册两个 Facade (config/app.php

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

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

1、如果你不使用这两个 Facade,你可以使用辅助函数 auth ()

2、auth () 是一个辅助函数,返回一个 guard,暂时可以看成 Auth Facade。

3、对于它有很多有必要说的,可以参考:Laravel 辅助函数 auth 与 JWT 扩展详解https://learnku.com/articles/10889/detailed-implementation-of-jwt-extensions

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

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

5. 修改 auth.php 

// @TODO 为了更好的学习,我在这里新建了一个web_api的路由模块儿
'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        //前后端分离接口
        'web_api' => [
            'driver' => 'jwt',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],

laravel如何配置自定义路由文件 

1、首先在routes目录下创建你要添加的自定义路由文件

2、修改app/Providers目录下RouteServiceProvider.php文件

3、修改app/Http目录下Kernel.php文件 

至此自定义路由文件配置完成

6. 注册路由(测试jwt-auth功能)

注意:在 Laravel 下,route目录下的路由文件,在实际接口路径中 默认都有前缀 api 。

Route::group(['prefix' => 'auth'], function ($router) {
Route::post('login', 'AuthController@login');
Route::post('logout', 'AuthController@logout');
Route::post('refresh', 'AuthController@refresh');
Route::post('me', 'AuthController@me');
});

 7. 创建 token 控制器(测试jwt-auth功能)

php artisan make:controller AuthController

说明: AuthController.php 文件的内容主要还是针对web页面(前后端分离)使用的。

本人在测试过程中遇到的问题:
1、使用  auth( 'web_api' )->attempt( $credentials ) 验证 token时,用户的密码格式 必须是 bcrypt() 加密的格式,否则验证的结果是空。

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{

    /**
     * 创建一个新的AuthController实例。
     * 要求附带mobile和password(数据来源users表)
     *
     * @return void
     */
    public function __construct()
    {
        // 这里额外注意了:官方文档样例中只除外了『login』
        // 这样的结果是,token 只能在有效期以内进行刷新,过期无法刷新
        // 如果把 refresh 也放进去,token 即使过期但仍在刷新期以内也可刷新
        // 不过刷新一次作废
        //$this->middleware('auth:api', ['except' => ['login']]);
        // 另外关于上面的中间件,官方文档写的是『auth:api』
        // 但是我推荐用 『jwt.auth』,效果是一样的,但是有更加丰富的报错信息返回
    }

    /**
     * 通过给定的凭证获得JWT。
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(Request $request)
    {
        $credentials = $request->only('mobile', 'password');
        if(!$token = auth( 'web_api' )->attempt( $credentials )){
            return response()->json( ['error' => 'Unauthorized'], 401 );
        }
        return $this->respondWithToken( $token );
    }

    /**
     * 获取已验证的用户。
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function me()
    {
        return response()->json( auth( 'web_api' )->user() );
    }

    /**
     * 注销用户(使令牌失效)。
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth( 'web_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( 'web_api' )->refresh() );
    }


    /**
     * 获取令牌数组结构。
     *
     * @param string $token
     *
     * @return \Illuminate\Http\JsonResponse
     */
    protected function respondWithToken( $token )
    {
        return response()->json( [
                                     'access_token' => $token,
                                     'token_type'   => 'bearer',
                                     'expires_in'   => auth( 'web_api' )->factory()->getTTL() * 60
                                 ] );
    }

}

二、JWT Token 详解

1. token 的获取、使用、删除和刷新

  • 1.1 获取 token

  • 1.2 使用 token 

有两种使用方法:

  1. 加到 url 中:?token=你的token
  2. 加到 header 中,建议用这种,因为在 https 情况下更安全:Authorization:Bearer 你的token

添加中间件保护的就需要使用 token 进行访问

可以使用的中间件有 auth、auth:api、jwt.auth、jwt.refresh、jwt.check、jwt.renew

关于这些中间件之间有什么差别,可以看我的另一篇文章:Laravel 辅助函数 auth 与 JWT 扩展详解

  • 1.3 删除 token

  • 1.4 刷新 token 

刷新token时需要注意的是: 通过 auth( 'web_api' )->logout() 操作之后的token,再去刷新时会报错,错误提示是:token 已被拉入黑名单,不能在刷新了。

2. token 的创建

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

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

  • 基于账密参数
  • 基于 users 模型返回的实例
  • 基于 users 模型中的用户主键 id
  1. 基于账密参数
// 使用辅助函数
$credentials = request(['email', 'password']); 
$token = auth()->attempt($credentials)

// 使用 Facade
$credentials = $request->only('email', 'password');
$token = JWTAuth::attempt($credentials);
  1. 基于 users 模型返回的实例
// 使用辅助函数
$user = User::first();
$token = auth()->login($user);

// 使用 Facade
$user = User::first();
$token = JWTAuth::fromUser($credentials);
  1. 基于 users 模型中的主键 id
// 使用辅助函数
$token = auth()->tokenById(1);

// 使用 Facade
源码中没找到

3. token 的解析

  • 解析 token 到对象
// 把请求发送过来的直接解析到对象
JWTAuth::parseToken();
  • 获取 token 中的 user 信息
// 辅助函数
$user = auth()->user();

// Facade
$user = JWTAuth::parseToken()->authenticate();
  • 获取 token

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

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

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

4. 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)

三、附录

1. JWT 的 两个 Facade

  • 1.1 JWTAuth

JWTAuth::parseToken()->方法() 一般都可以换成 auth()->方法()。
  • token 生成 attempt

根据 user 账密新建一个 token。

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

fromUser or fromSubject

根据 user 对象生成一个 token。后者是前者别名。

$user = User::find(1);
$token = JWTAuth::fromUser($user);
  • token 控制 refresh 更新 token。
$newToken = JWTAuth::parseToken()->refresh();

invalidate 让一个 token 无效。

JWTAuth::parseToken()->invalidate();

check 检验 token 的有效性。

if(JWTAuth::parseToken()->check()) {
    dd("token是有效的");
}
  • token 解析

authenticate or toUser or user
这三个效果是一样的,toUserauthenticate 的别名,而 user 比前两者少一个 user id 的校验,但并没有什么影响。

$user = JWTAuth::parseToken()->toUser();

parseToken

从 request 中解析 token 到对象中,以便进行下一步操作。

JWTAuth::parseToken();

getToken

从 request 中获取 token。

// 这个不用 parseToken ,因为方法内部会自动执行一次
$token = JWTAuth::getToken();  

 jwt-auth官方参考链接:Quick start - jwt-auth

 学习参考链接:JWT 完整使用详解 | Laravel China 社区 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值