Laravel 8 使用 JWT
tags: Web
PHP
Laravel
API
Auth
category: Back-End
description: Laravel 8 安裝與使用 JWT (json web token)
created_at: 2021/06/28 04:00:00
先開一個新的Laravel Project吧!
$ laravel new jwt-auth-app
事前準備
- 設定好你的.env
- 執行
php artisan migrate
產生 users 資料表
透過 Composer 安裝 jwt 套件
$ composer require tymon/jwt-auth
設定 config/app.php
'providers' => [
...,
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
'aliases' => [
...,
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
],
產生 config/jwt.php
$ php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
在 .env 產生 jwt secret key
$ php artisan jwt:secret
會在 .env 中看到類似以下的東西
JWT_SECRET=jwt_secret_key
設定你的 User Model
去實作JWTSubject
介面,他在Tymon\JWTAuth\Contracts\JWTSubject
,必須實現下面兩個方法
- getJWTIdentifier()
- getJWTCustomClaims()
example:
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
...
/**
* 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 [];
}
}
設定 config/auth.php
'defaults' => [
'guard' => 'api',
...
],
'guards' => [
...,
'api' => [
'driver' => 'jwt',
...
],
],
建立 Controller 測試
$ php artisan make:controller AuthController
填入以下程式碼,沒有做validation,只講求jwt運作正常
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function login(Request $request)
{
$credentials = $request->only(['email', 'password']);
if (!$token = auth()->attempt($credentials)) {
return response()->json('Unauthorized.', 401);
}
return response()->json([
'token' => $token,
'expires_in' => auth()->factory()->getTTL() * 60
]);
}
public function logout()
{
auth()->logout();
return response()->json();
}
public function userProfile()
{
return response()->json(auth()->user());
}
public function refreshToken()
{
$token = auth()->refresh();
return response()->json([
'token' => $token,
'expires_in' => auth()->factory()->getTTL() * 60
]);
}
}
註冊路由
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
Route::post('/logout', [AuthController::class, 'logout']);
Route::post('/refresh', [AuthController::class, 'refreshToken']);
Route::get('/user-profile', [AuthController::class, 'userProfile']);
測試
建立 UserSeeder
$ php artisan make:seeder UserSeeder
他會存在 database/seeders資料夾中,然後填入以下內容
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::create([
'name' => 'test',
'email' => '[email protected]',
'password' => Hash::make('1234')
]);
}
}
在DatabaseSeeder.php中註冊
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call([
UserSeeder::class
]);
}
}
執行seeder
$ php artisan db:seed
執行伺服器
$ php artisan serv
打開你的 API 測試軟體
Endpoint: /login
傳入
{
"email": "[email protected]",
"password": "1234"
}
輸出
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODgwMFwvYXBpXC9sb2dpbiIsImlhdCI6MTYyNDg3NzIyOSwiZXhwIjoxNjI0ODgwODI5LCJuYmYiOjE2MjQ4NzcyMjksImp0aSI6IloySlNYMm5aMFFFcFdBZGQiLCJzdWIiOjEsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjcifQ.7EPqF9WCOdzNpoZar0oq6Vq9YjUZMvfKSEKxpf3fmy0",
"expires_in": 3600
}
接下來在 header 帶入 Bearer Token,格式如下
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODgwMFwvYXBpXC9sb2dpbiIsImlhdCI6MTYyNDg3NzIyOSwiZXhwIjoxNjI0ODgwODI5LCJuYmYiOjE2MjQ4NzcyMjksImp0aSI6IloySlNYMm5aMFFFcFdBZGQiLCJzdWIiOjEsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjcifQ.7EPqF9WCOdzNpoZar0oq6Vq9YjUZMvfKSEKxpf3fmy0
Endpoing: /user-profile
{
"id": 1,
"name": "test",
"email": "[email protected]",
"email_verified_at": null,
"created_at": "2021-06-28T10:44:02.000000Z",
"updated_at": "2021-06-28T10:44:02.000000Z"
}
Endpoint: /refresh
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODgwMFwvYXBpXC9yZWZyZXNoIiwiaWF0IjoxNjI0ODc3NDg1LCJleHAiOjE2MjQ4ODExNDMsIm5iZiI6MTYyNDg3NzU0MywianRpIjoidE5lZGs2ZVoxUzRUb09NQyIsInN1YiI6MSwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.vsOMcdKNbO8WUAPYi7F1JoeQ0mgIUUVVsY1qHsPIlbY",
"expires_in": 3600
}
再來需要使用新的token,舊的已經不可用
Endpoint: /logout
[]
登出完成!
最後更新時間: 2021年06月28日.