Laravel拓展之jwt-auth

一.安装jwt-auth。

这里我们用 composer 来安装它,在 laravel5.5 的版本中适配的 jwt-auth 拓展版本为 1.00-rc.2

$ composer require tymon/jwt-auth:1.0.0-rc.2

安装完成了后,发布配置文件:

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

接着我们需要设置一下 JWT 的 secret , secret 在上一篇文章已经讲过,就是加密生成签名的密钥,这个密钥我们不能让它泄露,并且如果跟换它的话,会导致以前的 token 全部无效。这里我们用下面的命令来生成一个 secret.

$ php artisan jwt:secret

这个时候我们去 .env 文件中可以看到最下面多了一行:

JWT_SECRET=B9iJ1ACva0x51eSXWtu8JWTNxRNQdlO0

接下来修改 config/auth.php如下图所示。

现在我们已经将jwt-auth集成到了laravel,下面我们先来看看jwt-auth中有那些方法可以供我们调用:

二.jwt-auth中的可用方法。

1.基础的方法。

  • attemept() :校验登陆信息是否正确,正确返回 token 值,不正确返回 null
$token = auth()->attempt($credentials);
  • login() :记录一个用户并返回对用的 token
//获取一个用户
$user = User::first();
//为该用户生成 token 保存并返回。
$token = auth()->login($user);
  • user() : 获取请求中的 token 对应的用户信息。
$user = auth()->user();
  • userOrFail() : 获取当前请求中 token 中对应的用户模型,如果没有则抛出一个异常。
try{
    $user = auth()->userOrFail();
}catch(\Tymon\JWTAuth\Exceptions\UserNotDefindException $e){

}
  • logout() : 用户退出登陆,销毁退出用户的当前可用 token。
auth()->logout();
//通过true参数将销毁的参数加入黑名单,永远不能使用
auth()->logout(true);
  • refresh() : 刷新当前登陆用户的 token ,返回刷新后的 token。
$newToken = auth()->refresh();

//第一个参数如果为true,则重置的 token 将永远进入黑名单,第二个参数我也不清楚,
$newToken = auth()->refresh(true,true);
  • invalidate() : 失当前的的 token 失效,加入黑名单。
auth()->invalidate();

//如果参数为true,则失效的 token 永久加入黑名单。
auth()->invalidate(true);
  • tokenById() : 通过用户表的id来获取对应用户的 token。
$token = auth()->tokenById(1);
  • payload() : 获取token中的 payload。
$payload = auth()->payload();

//可以通过下面的方式来操作。
$payload->get('sub'); // = 123
$payload['jti']; // = 'asfe4fq434asdf'
$payload('exp') // = 123456
$payload->toArray(); // = ['sub' => 123, 'exp' => 123456, 'jti' => 'asfe4fq434asdf'] etc
  • validate() : 验证用户登陆信息是否合法。
if(auth()->validate($credentials)){
    
}

2.高级的用法。

  • 生成 token 动态的添加payload中的值
$token = auth()->claims(['foo' => 'bar'])->attrmpt($credentials);
  • Set the token explicitly
$user = auth()->setToken('eyJhb...')->user();
  • Set the request instance explicitly
$user = auth()->setRequest($request)->user();
  • Override the token ttl
$token = auth()->setTTL(7200)->attempt($credentials);

三.jwt-auth的使用。

使用之前,文档值这么说的:

Firstly you need to implement the TymonJWTAuthContractsJWTSubject contract on your User model, which requires that you implement the 2 methods getJWTIdentifier() and getJWTCustomClaims().

我们应该在用户模型实现 JWTSubject接口并实现 getJWTIdentifier()getJWTCustomClaims()

来看看官方给出得例子。

  • 用户模型 Users.php
<?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;

    // 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 [];
    }
}
  • api 路由文件 route/api.php
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');
});
  • 创建的测试测试控制器 AuthController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    /**
     * Create a new AuthController instance.
     *
     * @return void
     */
    public function __construct()

    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }
    
    /**
     * Get a JWT via given credentials.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login()
    {
        $credentials = request(['email', 'password']);
        if (! $token = auth()->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()->user());
    }

    /**
     * Log the user out (Invalidate the token).
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function logout()
    {
        auth()->logout();
        return response()->json(['message' => 'Successfully logged out']);
    }

    /**
     * Refresh a token.
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function refresh()
    {
        return $this->respondWithToken(auth()->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()->factory()->getTTL() * 60
        ]);
    }
}

现在我们来通过 postMan 来测试一下。

  • {{host}}/api/auth/login接口。

  • {{host}}/api/auth/me接口。

  • {{host}}/api/auth/refresh接口。

  • {{host}}/api/auth/logout接口。

其它方法我就不测试了,你们有兴趣你们自己去一个一个的测试吧。

四.再多说一句。

jwt 的判断原理是通过将 token 拆分为header、payload、signature。然后在服务端将拆分后的 header 和 payload 与 服务端的密钥生成 新的signature 。然后和拆分后的signature 做比较,如果相等就说明token有效。
还可以将token和对应的用户数据存起来,用来做校验。
具体的可以查看上一篇博文 JWT详细解读

Snail's Blog
请先登录后发表评论
  • 最新评论
  • 总共0条评论
  • 本博客使用免费开源的 laravel-bjyblog v5.5.1.3 -develop 搭建 © 2014-2018 www.snail-c.cn 版权所有 ICP证:蜀ICP备18023253号-1
  • 联系邮箱:459921737@qq.com