Laravel中使用JWT

資料網址

jwt 官網文檔:https://jwt.io/
jwt-auth文檔:https://jwt-auth.readthedocs.io/en/develop/laravel-installation/php

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

安裝和配置

一、jwt的安裝不能直接 composer require tymon/jwt-auth(文檔上這樣得不到最新版)。
正確的安裝是這樣的: composer require tymon/jwt-auth:1.0.0-rc.4.1
後面的1.0.0-rc.4.1 是版本號(最新版本),在github上這個地方:
在這裏插入圖片描述
二、安裝完成以後 發佈配置(Publish the config)git

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

這個指令就是把jwt的配置發佈出,簡單點就是在config目錄下建立一個jwt的配置文件,同時也把jwt的組件服務加載到項目中,以後就能夠經過在env的配置中修改github

三、生成祕鑰(Generate secret key)web

php artisan jwt:secret

這個命令會在env中增長一個JWT_SECRET,同咱們的APP_KEY這個secret是十分重要的,用於給Token簽名,更換這個secret會致使以前生成的全部token無效,因此不要隨意的替換這個secret.ajax

測試jwt是否可使用

在文檔中描述了,是須要模型實現jwt的接口,同時重寫這兩個方法分別是
getJWTIdentifier與getJWTCustomClaims(https://jwt-auth.readthedocs.io/en/develop/quick-start/):
在這裏插入圖片描述
本身的代碼中這樣寫:json

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class Member extends Authenticatable implements JWTSubject
{
    protected $table = 'members';

    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 [];
    }
}

使用tinker測試:api

php artisan tinker
$user = App\User::find(1);
$str = JWTAuth::fromUser($user);//獲得一個結果,複製這份數據到JWT官網,以下圖1
Base64_decode($str);//也能夠解密:

圖1:
在這裏插入圖片描述
第二部分的內容
sub是指用戶的id,而這個信息就是由模型中重寫的getJWTIdentifier返回的數據內容
prv 是擴展包自定義的字段也就是模型名的哈希值,做用就是區別不一樣的模型,在多用戶的時候就會有一個很是的關鍵性做用
第三部分的簽名
是在簽名php artisan jwt:secret建立的 在這裏插入圖片描述數組

laravel中使用

一、配置auth驅動爲jwt安全

而後配置config/auth的內容,可讓laravel系統直接使用jwt進行相關的驗證操做。
默認api中的配置是系統自帶的認證機制。而能夠選擇修改成採用jwt的方式(固然也可使用門面)

在這裏插入圖片描述
把以前的token驅動改爲jwt的驗證方式:
在這裏插入圖片描述
修改完driver 爲jwt以後,修改users對應的模型:
在這裏插入圖片描述
而後使用tinker測試一下:

php artisan tinker
$user = ['email'=>'zwitting@example.net','password'=>'secret']
auth('api')->attempt($user);

在這裏插入圖片描述
二、在控制器中使用

首先建立控制器:

php artisan make:controller Api\V1\AuthController

而後控制器提供三個方法:login 登入、logout 退出登入、刷新
refresh 刷新token機制 (由於token它不能一直有效這樣對於程序仍是用戶都不是很安全的,那樣就很是危險。因此這裏會提供一個token的刷新的方法。用戶刷新 用戶的token以保證用戶的正常登入<而且這樣就能夠不須要重複登入獲取token>)
在這裏插入圖片描述
AuthController文件中的三個方法:

<?php
namespace App\Http\Controllers\Api\V1;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class AuthController extends Controller
{
    //這是使用Laravel中Trait建立的給客戶端返回數據,具體怎麼用查看相關資料
    use TransFormer;
    public function login(Request $request)
    {
        $data = $request->only('email', 'password');
        if (!($token = auth('api')->attempt($data))) {
            return $this->transFormer(40000, 'email or password error');
        }
        return $this->transFormer(10000, 'login success', ['token' => $token]);
    }
    public function logout(Request $request)
    {
        auth('api')->logout();
        return $this->transFormer(10000, 'logout success');
    }
    public function refresh(Request $request)
    {
        return $this->transFormer(10000, null, ['token' => auth('api')->refresh()]);
    }
}

api.php 裏面對應的路由:

Route::namespace('Api\V1')->group(function(){
    Route::post('login', 'AuthController@login');
    Route::post('logout', 'AuthController@logout');
    Route::post('refresh', 'AuthController@refresh');
    Route::get('user','AuthController@user');
});

在這裏插入圖片描述

而後在postman裏面測試:
在這裏插入圖片描述

而後能夠經過laravel中默認提供的路由來對於該token進行解析:
在這裏插入圖片描述
在這裏插入圖片描述
注意實際上通常都不會直接在url後沒追加這個token,
而是會把token作爲 Authorization,type 爲bearer Token以下:
在這裏插入圖片描述
若是設置在header中的話,以下設置:
設置在header中而後經過設置:
key爲 Authorization value 爲 bearer+空格+token
注意bearer 後面必定要跟上一個空格再添加token
在這裏插入圖片描述
最後配置內容:
在這裏插入圖片描述
在這裏插入圖片描述
這就是jwt在laravel中使用的所有內容,若有不足,歡迎指正…

補充內容:JWT在tp5裏面的使用

一、首先 composer 安裝 firebase/php-jwt

github:https://github.com/firebase/php-jwt

composer require firebase/php-jwt

二、使用

當用戶登陸時,若是有 token 而且沒有過時,則獲得用戶信息,若是 token過時,或者是新用戶,則生成一個token具體業務自已看着辦,這裏只討論使用

下面是爲用戶頒發 token

public function getToken(){
        $key = "123456";  //這裏是自定義的一個隨機字串,應該寫在config文件中的,解密時也會用,至關    於加密中經常使用的 鹽  salt
        $token = [
            "iss"=>"",  //簽發者 能夠爲空
            "aud"=>"", //面象的用戶,能夠爲空
            "iat" => time(), //簽發時間
            "nbf" => time()+100, //在何時jwt開始生效  (這裏表示生成100秒後才生效)
            "exp" => time()+7200, //token 過時時間
            "uid" => 123 //記錄的userid的信息,這裏是自已添加上去的,若是有其它信息,能夠再添加數組的鍵值對
        ];
        //注意此處沒有第三個參數 ['HS256']
        $jwt = JWT::encode($token,$key); //根據參數生成了 token
        return json([
            "token"=>$jwt
        ]);
    }

上面生成了token並返回給的客戶端,之後客戶端再訪問時,就帶上 token 信息,就能夠知道用戶的信息了

方法以下

$jwt = input("token");  //上一步中返回給用戶的token
  $key = "123456";  //上一個方法中的 $key 本應該配置在 config文件中的
 //注意這個jwt有個bug。解密的時候 必須加第三個參數["HS256"
  try{
           $token = (array)JWT::decode($auth,$this->key,['HS256']);
           if($token['exp']<time()) {
               return $this->ajax('-1','token expired');
           }
           $data = (array)$token['data'];
           $this->_userId = $data['id'];
       }catch (\Exception $e) {//特別注意 這個地方必須加 \,不加的話會有坑,具體本身調試。緣由就是 Exception 類的命名空間問題。這裏不在贅述.......
           return $this->ajax('-1',$e->getMessage());
       }
       $info = JWT::decode($jwt,$key,["HS256"]); //解密jwt

返回:

{
    "iss": "",
    "aud": "",
    "iat": 1544457210,
    "nbf": 1544457310,
    "exp": 1544464410,
    "uid": 123

從返回的結果中能夠取到 uid 就能夠獲得 當前user的全部信息了.