---
# System prepended metadata

title: laravel實作JWT登入驗證機制

---

# laravel實作JWT登入驗證機制

## 安裝JWT套件
JWT(Json Web Token)是一種對token進行編碼的方式，想了解詳情可到參考資料裡找到JWT的介紹。

首先在laravel專案底下打開命令提示字元，輸入以下指令安裝JWT套件：

```
composer require tymon/jwt-auth
```

輸入以下指令，將JWT的資源檔複製到定的位置。

```
php artisan vendor:publish
```

輸入完後會出現一個列表，接著輸入JWT的編號，就可以安裝完成了。

## 設定.env
打開專案中的.env，在最下方輸入以下程式碼：

``` php
JWT_TTL=1440 //設定token時限為1440分鐘
```

打開命令提示字元，建立JWT的secret：

```
php artisan jwt:secret
```

再打開.env檔，就會看到系統幫忙生成一個JWT的secret字串囉!

## 設定Model

- app\models\User.php
打開User.php，新增getJWTIdentifier和getJWTCustomClaims這兩個方法，如下列所示：

``` php=1
<?php

namespace App\Models;

use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable implements JWTSubject
{
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable =   
       ['name', 'email', 'password'];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

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

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

```

## 設定auth.php
- config\auth.php

將程式碼中guards=>api=>driver的部分修改成：

```php
'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

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

## 設定controller
- app\Http\controllers\api\AuthController.php

請自行建立一個Controller，不會的可以參考之前的教學。

```php=1
<?php

namespace App\Http\Controllers\api;

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

class AuthController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api')->except('login');
    }
    
    public function login(Request $request)
    {
        $credentials = request(['email', 'password']);

        if (! $token = auth()->attempt($credentials)) {
            return response()->json(['status' => 1, 'message' => 'invalid credentials'], 401);
        }

        return response()->json(['status' => 0, 'token' => $token]);
    }

    public function me()
    {
        return response()->json(auth()->user());
    }

    public function logout()
    {
        auth()->logout();
        return response()->json(['status' => 0]);
    }

}
```
程式碼中，__construct是指該類別建構時要執行的程式，這邊就是設定middleware，代表每當使用這個api的時候，都會經過auth的中繼站，請auth來幫我們驗證使用者是否有登入。以及排除login的方法，否則連login都要使用token，沒有登入哪裡來的token!

第20行的意思是取得request中的email和password參數，第22行是將這組帳號密碼進行驗證，如果驗證成功的話就回傳一組token，否則就回傳錯誤訊息。

:::warning
在登入的地方，laravel會自動將輸入的密碼做bcrypt加密，這邊要特別注意。
:::

## 測試
打開Postman進行測試，在header的地方要加上下列數值：

|key|value|
|-|-|
|Accept|application/json|
|Authorization|Bearer +Your Token|

接著試著登入看看吧!

:::warning
假設拿到的token為"12345"，那麼Authorization的值則為"Bearer 12345"
:::

## 刷新token
刪除目前的token:

```
auth()-> invalidate();
```

用目前的token去取得一個新的token:
```
$token = auth()->fromUser(auth()->user());
```

這兩行程式碼可以寫在確認自己身分的API中，以本範例來說就是在AuthController的me方法裡面，先將傳進API中的token銷毀，在利用同一個使用者去產生一個新的API回傳回去。

## 參考資料
[Laravel 與 JWT 搭配運用](https://hackmd.io/@8irD0FCGSQqckvMnLpAmzw/SkqRnxqIM?type=view)
[Authenticating a Laravel API](https://www.youtube.com/watch?v=TTK8uQOjpT0&ab_channel=DigitalOcean)
[Securing a Laravel API in 20 minutes with JWTs](https://www.youtube.com/watch?v=6eX9Pj-GhZs&ab_channel=AndrewSchmelyun)
[How to Setup Jwt Token in laravel in Rest API](https://www.youtube.com/watch?v=VtAxYez4ZdQ&ab_channel=LaravelPackageTutorial)
[[筆記] 透過 JWT 實作驗證機制](https://medium.com/%E9%BA%A5%E5%85%8B%E7%9A%84%E5%8D%8A%E8%B7%AF%E5%87%BA%E5%AE%B6%E7%AD%86%E8%A8%98/%E7%AD%86%E8%A8%98-%E9%80%8F%E9%81%8E-jwt-%E5%AF%A6%E4%BD%9C%E9%A9%97%E8%AD%89%E6%A9%9F%E5%88%B6-2e64d72594f8)