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.php 的 providers 配置項中注冊服務提供者

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 = JWTAuth::attempt($credentials)) {
            return response()->json(['result'=>'failed']);
        }
        return $this->responseWithToken($token);
    }

    /**
    * 刷新token
    */
    public function refresh()
    {
        return $this->responseWithToken(JWTAuth::refresh());
    }

    /**
    * 退出登錄
    */
    public function logout(Request $request)
    {
        JWTAuth::logout();
    }

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

        return response()->json($response);
    }
}

原文地址:https://www.stephen520.cn/blog/10255


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM