JWT 實現 Laravel 認證(前後端分離專案必備)

Alexander-發表於2021-02-09

通過 composer 安裝 jwt

composer require tymon/jwt-auth

新增服務提供商(Laravel 5.4或更低版本)

將服務提供者新增到配置檔案中的 providers 陣列中 config/app.php,如下所示:

config/app.php

'providers' => [  
    ...  
    Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
]

釋出配置

執行以下命令以釋出程式包配置檔案:

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

現在,您應該擁有一個 config/jwt.php 檔案,該檔案可讓您配置此軟體包的基礎。

生成 JWT 金鑰

php artisan jwt:secret

這將使用以下方式更新您的 .env 檔案 JWT_SECRET=foobar
這是將用於對令牌進行簽名的金鑰。具體如何發生將取決於您選擇使用的演算法。

更新 User 模型

首先,您需要 Tymon\JWTAuth\Contracts\JWTSubject 在 User 模型上實現,這要求您實現 getJWTIdentifier() 和方法 getJWTCustomClaims()

app/Models/User.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;

    .
    .
    .

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

注意:一定要有 implements JWTSubject(第 9 行),不要忽略了。

配置授權

注意:僅在使用 Laravel 5.2 及更高版本時,此方法才有效。
config/auth.php 檔案內部,您需要進行一些更改,以配置 Laravel 使用 jwt 防護來增強您的應用程式身份驗證。

config/auth.php

'defaults' => [
    'guard' => 'api',
    'passwords' => 'users',
],

.
.
.

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

新增一些基本的身份驗證路由

讓我們新增一些路由,routes/api.php 如下所示:

routes/api.php

Route::group([ 'namespace' => 'Api' ], function($router) {
    $router->post('login', 'AuthController@store');
    $router->match([ 'patch', 'put' ], 'refresh', 'AuthController@update');
    $router->delete('logout', 'AuthController@destroy');
    $router->any('me', 'UserController@show');
});

建立 AuthController

我們可以通過手動或執行 artisan 命令來建立:

php artisan make:controller Api\\AuthController

app/Http/Controllers/Api/AuthController.php

<?php

namespace App\Http\Controllers\Api;

use App\Http\Requests\AuthRequest;
use App\Presenters\AuthPresenter;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class AuthController extends Controller
{
    protected $auth;

    public function __construct(AuthPresenter $authPresenter)
    {
        $this->auth = authPresenter;

        $this->middleware('auth:api', [
            'only' => [ 'update' ]
        ]);
    }

    public function store(AuthRequest $request)
    {
        $credentials = $request->validated();

        if ( ! $token = Auth::attempt($credentials) ) {
            return response()->json([
                'error' => '很抱歉,您的郵箱和密碼不匹配。'
            ]);
        }

        return $this->auth->respondWithToken($token);
    }

    public function update()
    {
        $newToken = auth()->refresh();

        return $this->auth->respondWithToken($newToken);
    }

    public function destroy()
    {
        Auth::logout();

        return [];
    }
}

建立 AuthPresenter

app 目錄下新建 Presenters 資料夾,接著在 Presenters 資料夾下新建 AuthPresenter.php 檔案。

app/Presenters/AuthPresenter.php

<?php

namespace App\Presenters;

class AuthPresenter
{
    public function respondWithToken($token)
    {
        return response()->json([
            'token' => $token,
            'token_type' => 'Bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]);
    }
}

建立 AuthRequest

我們可以通過手動或執行 artisan 命令來建立:

php artisan make:request AuthRequest

app/Http/Requests/UserRequest.php

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class AuthRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'email' => 'required|email',
            'password' => 'required'
        ];
    }
}

注意:return false 一定要改成 return true(第 16 行)。

建立 UserController

我們可以通過手動或執行 artisan 命令來建立:

php artisan make:controller Api\\UserController

app/Http/Controllers/Api/UserController.php

<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;

class UserController extends Controller
{
    public function show()
    {
        $user = $this->authUser();

        return $user;
    }
}

更新 Controller

app/Http/Controllers/Controller.php

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\UserNotDefinedException;

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function authUser()
    {
        try {
            $user = Auth::userOrFail();
        } catch (UserNotDefinedException $e) {
            return response()->json([
                'error' => $e->getMessage()
            ]);
        }

        return $user;
    }
}

好了,下面進入測試環節。

測試環節

第一步:開啟 postman
JWT 實現 Laravel 認證(前後端專案必備)

第二步:點選 左上角 的
JWT 實現 Laravel 認證(前後端專案必備)

第三步:輸入資訊嘗試登入

  • 輸入正確的資料
    JWT 實現 Laravel 認證(前後端專案必備)
    我們可以看到已經獲取到了 token 引數

    {
      "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvd3d3LmFjZXdhbmdwYWkuY29tXC9hcGlcL2xvZ2luIiwiaWF0IjoxNjEyODQ4MTY1LCJleHAiOjE2MTI4NTE3NjUsIm5iZiI6MTYxMjg0ODE2NSwianRpIjoiZDdueFFPQkNNMzRsaU03eiIsInN1YiI6NywicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.xWUgBdyhi5QCVgUQQe9pE-1pRLC64WPwKGRH8bjtcuU", // token 引數
      "token_type": "Bearer", // token 型別
      "expires_in": 3600 // 有效時間(s)
    }
  • 輸入錯誤的資料
    JWT 實現 Laravel 認證(前後端專案必備)
    我們可以看到沒有獲取到 token 引數

    {
      "error": "很抱歉,您的郵箱和密碼不匹配"
    }

第四步:複製 token 獲取已經授權的使用者資訊

  • 填寫正確的 token 引數
    JWT 實現 Laravel 認證(前後端專案必備)
    我們可以看到使用者資訊已經被顯示出來了
    {
      "id": 7,
      "name": "Tony",
      "email": "75692074@qq.com",
      "email_verified_at": null,
      "created_at": "2021-02-07T05:07:16.000000Z",
      "updated_at": "2021-02-07T05:07:16.000000Z"
    }
  • 填寫錯誤的 token 引數
    JWT 實現 Laravel 認證(前後端專案必備)
    我們可以看到程式拋錯了
    {
      "error": "An error occurred"
    }

好了,教程就到這裡了。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章