1. 程式人生 > 其它 >Laravel Api實現JWT Token認證

Laravel Api實現JWT Token認證

在開發Api時,處理客戶端請求之前,需要對使用者進行身份認證,Laravel框架預設為我們提供了一套使用者認證體系,在進行web開發時,幾乎不用新增修改任何程式碼,可直接使用,但在進行api開發時,需要我們自己去實現,並且Laravel框架預設提供的身份認證不是jwt的,需要在資料庫中增加api_token欄位,記錄使用者認證token並進行身份校驗,如果需要使用jwt,無需新增欄位,需要藉助三方庫來實現。

Token認證原理

  1. 客戶端傳送認證資訊 (一般就是使用者名稱 / 密碼), 向伺服器傳送請求

  2. 伺服器驗證客戶端的認證資訊,驗證成功之後,伺服器向客戶端返回一個 加密的 token (一般情況下就是一個字串)

  3. 客戶端儲存 (cookie, session, app 中都可以儲存) 這個 token, 在之後每次向伺服器傳送請求時,都攜帶上這個 token

  4. 伺服器驗證這個 token 的合法性,只要驗證通過,伺服器就認為該請求是一個合法的請求

JWT概述

token 只是一種思路,一種解決使用者授權問題的思考方式,基於這種思路,針對不同的場景可以有很多種的實現。而在眾多的實現中,JWT (JSON Web Token) 的實現最為流行.

JWT 這個標準提供了一系列如何建立具體 token 的方法,這些緣故方法和規範可以讓我們建立 token 的過程變得更加合理和效率.

比如,傳統的做法中,伺服器會儲存生成的 token, 當客戶端傳送來 token 時,與伺服器的進行比對,但是 jwt 的不需要在伺服器儲存任何 token, 而是使用一套加密 / 解密演算法 和 一個金鑰 來對使用者發來的 token 進行解密,解密成功後就可以得到這個使用者的資訊.

這樣的做法同時也增加了多伺服器時的擴充套件性,在傳統的 token 驗證中,一旦使用者發來 token, 那麼必須要先找到儲存這個 token 的伺服器是哪臺伺服器,然後由那一臺伺服器進行驗證使用者身份。而 jwt 的存在,只要每一臺伺服器都知道解密金鑰,那麼每一臺伺服器都可以擁有驗證使用者身份的能力.

這樣一來,伺服器就不再儲存任何使用者授權的資訊了,也就解決了 session 曾出現的問題.

實現方法

1.安裝jwt-auth

composer require tymon/jwt-auth:dev-develop

參考文件:

https://github.com/tymondesigns/jwt-auth/wiki/Installation

2.在config/app.phpproviders配置項中註冊服務提供者

Tymon\JWTAuth\Providers\LaravelServiceProvider::class,

3.生成配置檔案

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

此命令會在config目錄下生成jwt.php配置檔案

4.生成金鑰

php artisan jwt:secret

此命令會在你的.env檔案中新增一行JWT_SECRET=secret

5.建立模型

php artisan make:model Models/User

程式碼:

<?php

namespace App\Models;

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

class User extends Authenticatable implements JWTSubject
{

    protected $fillable = ['name', 'password'];

    protected $hidden = ['password', 'remember_token'];

    //
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    public function getJWTCustomClaims()
    {
        return [];
    }
}

6.修改配置檔案auth.php

 'guards' => [
        'api' => [
            'driver' => 'jwt',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class
        ],
    ],

7.實現登入註冊返回token

php artisan make:controller Api/UserController
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Member;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;

class PassportController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['register', 'login']]);
    }

    /**
    * 使用者註冊
    */
    public function register(Request $request)
    {
        // jwt token
        $credentials = [
            'name' => $request->name,
            'password' => Hash::make($request->password)
        ];
        $user = User::create($credentials);
        if($user){
            $token =  = JWTAuth::fromUser($user);
            return $this->responseWithToken($token);
        }
    }

    /**
    * 使用者登入
    */
    public function login(Request $request)
    {
        // todo 使用者登入邏輯

        // jwt token
        $credentials = $request->only('name', 'password');
        if (!$token = auth()->attempt($credentials)) {
            return response()->json(['result'=>'failed']);
        }
        return $this->responseWithToken($token);
    }

    /**
    * 重新整理token
    */
    public function refresh()
    {
        return $this->responseWithToken(auth()->refresh());
    }

    /**
    * 退出登入
    */
    public function logout(Request $request)
    {
        auth()->logout();
    }

    /**
    * 響應
    */
    private function responseWithToken(string $token)
    {
        $response = [
            'access_token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ];

        return response()->json($response);
    }
}
原文地址:https://www.stephen520.cn/blog/10255