PHP + Laravel 雞排聯盟API實作: 追加會員身份驗證

by 班陳
Chicken_Affiliate

前言

身為一個後端攻城屍
沒事就是在寫驗證管權限什麼的
今天就是要來寫一個限權管理機制
好確保我們的雞排資料不會被奇怪的人亂改亂修

好的 準備好就開始吧!

增加註冊功能

Laravel 很貼心地提供了快速的指令
可以直接生成前端畫面和設置權限的相關 Routes
指令如下:

composer require laravel/ui --dev

php artisan ui vue --auth

file

file

這邊可以用Git看一下新增了什麼
file

可以得知新增了一個HomeController

同時我們可以看一下web.php(管前端畫面的路由)
file
可以發現 Laravel 自動幫我們追加了一個/home的路由進去

這邊我可以用command line看一下目前的路由狀況

php artisan route:list

file
可以看到紅框框起來的地方就是這次新增的路由
基本的會員登錄驗證都已經在Laravel大大的幫助下完成了

你可能會問,那DB勒?
沒問題! Laravel 在 new 專案出來的時候也已經自帶好了
file

這個時候
只要進入我們用 Valet 架好的本地環境
就可以看到登錄/註冊畫面囉
file

超方便的!
輸入好資料後就可以註冊完成了

下一步呢?
就是要來寫驗證會員身份啦!

使用Passport做會員身份驗證

建議可以先行服用看官方文件 安裝好官方推薦的passport做OAuth2驗證
就可以輕易地讓我們的API來使用Token驗證 user
https://laravel.com/docs/6.x/passport

step 1

composer require laravel/passport

file

composer.json就可以看到passport
file

step 2


接著來讓passport幫我們加入相關的table

php artisan migrate

file

可以看到passport加入了client tabletoken table
這個概念可以想像成白名單
也就是說
如果有人要來存取我們的API
首先 user 必須要被加到白名單內(client table)
接著在確認 user 是白名單的成員後
api 端才能核發 Token 給 user 以獲取會員的權限

一般在做任何需要認證的請求時
比如說(我「想」要新增雞排店)
那麼就要先跟伺服器請求核發一組 Access Token(就是一段亂碼)
把這個 Token 附帶在請求中
就可以操作需要驗證的API (我要新增雞排-附帶有效的Token)

step 3


創建加密需要的公鑰私鑰
這主要是讓我們在接著可以安全產生 Access Token
使用方式在後面會做介紹

php artisan passport:install

file

step 4


設定Passport
有了以上的預備
接著我們要來做一些設定
把這個passport給引用到我們user的model中

<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens; // 加這行

class User extends Authenticatable
{
    use HasApiTokens, Notifiable; // 加這行
    use Notifiable;
}

這樣子我們就加入了 Passport 寫好的方法

step 5


接著 AuthServiceProvider 中的 boot 方法中調用 Passport::routes 方法
這個方法會註冊必要的路由去核發、換發、撤銷 Token
以及請求客戶端的 id、secret 之類的路由

<?php

namespace App\Providers;

use App\ChickenFilletShop;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use Laravel\Passport\Passport;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Passport::routes();  // 加這行
    }
}

完成後
就可以看到路由表以下
紅框處就是我們調用passport方法所新增的路由了!
file

ps. passport核發的token預設是1年有效

step 6


修改config

讓我們到config/auth.php

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

        'api' => [
            'driver' => 'passport', // 把原來的 token 改成 passport
            'provider' => 'users',
            'hash' => false,
        ],
    ],

申請授權

在上面的步驟中
我們安裝也設定好了passport
接下來就是要來使用它並設定權限了

首先要提的是
Laravel 提供了4種不同的授權類型

  1. 密碼授權
  2. 授權碼授權
  3. 個人授權
  4. 同步授權

而以下將對密碼授權進行說明

如先前所說
在請求API,首先必須確認 user 在白名單(client table)內
這才有辦法使用idsecret來申請Access Token
接著才能拿著這個Access Token來請求API

而當 User 在申請Access Token
設定資料如下:

POST /oauth/token HTTP/1.1
Content-type: application/x-www-form-urlencoded

須附帶資料如下:

<?php
  'grant_type' => 'password', //告訴伺服器密碼授權
  'client_id' => '2', // 伺服器端會有一筆client ID資料,在安裝Passport 有新增一組,日後若有需求可再新增。
  'client_secret' => 'Y9kRRtMX...',  //上面ID對應的 secret 值
  'username' => 'goodchicken@gmail.com', // 登入哪個使用者
  'password' => 'goodchicken@gmail.com', //密碼
  'scope' => '', //作用區

回傳的資料如下

 {
    "token_type": "Bearer",
    "expires_in": 31622400,
    "access_token": "eyJ0eXA...",
    "refresh_token": "def502..."
}

access_token
這樣就取得了`Access Token`
代表授權成功了! 接著我們就可以使用這個`Access Token`來請求須要驗證的API了!

但我們還沒有在系統中設定雞排resource成須要驗證才能操作
接下來就來完成這部份吧!

設定操作資源需驗證的方法

step 1


首先到這支檔案設定
`chickenFillet/app/Http/Controllers/ChickenFilletShopController.php`

除了`index`(查詢清單)和`show`(查詢單一筆資料)外,其他的action都要驗證

middleware('auth:api', ['except' => ['index','show']]);
    }

step 2


使用`Postman`來刪資料試試
看看是不是隨便一個 user 都可以把我們家資料刪掉
delete_without_auth

嗯看來是不行 會跳`401 error`
符合預期

step 3


還記得上面申請的`Access Token`嗎?

access_token

我們把上面`Access Token`給copy下來
並貼到header再打一次 API
header的寫法如下:
file

response 如下
delete

這樣子就成功囉!

ps. 若出現`Could not get any response`字串的話
file

那可能是因為在`Access Token`的時候貼錯
多貼了一行斷行
file

刪了這段就好了 真的冏

step 3


Laravel 預設`Access Token`是一年有效
(若要自訂有效期,可以參考官方文件
https://laravel.com/docs/5.8/passport#token-lifetimes)
在失效後,可以使用`Refresh Token`來取得新的`Access Token`
其設定如下:
header:

Content-Type: application/x-www-form-urlencoded
Accept: application/json

body

grant_type: refresh_token
refresh_token: def5020054....
client_id:2
client_secret: Y9kRRtMXcUrn29z7HPlyPIuju2IJpaQWwdq6rECo
scope:

完成後就可以看到新的Access Token

file

系列文章

最後附上系列文章

  1. PHP + Laravel 雞排聯盟API實作: 前言
  2. PHP + Laravel 雞排聯盟API實作: 產出 table 及可供操作的物件
  3. PHP + Laravel 雞排聯盟API實作: CRUD 增刪改查
  4. PHP + Laravel 雞排聯盟API實作: 追加會員身份驗證

以及初學時看的書 推薦!

還有gibhub連結

參考資料

https://laravel.com/docs/6.x/authentication
https://learnku.com/laravel/t/10488/could-not-get-any-response

You may also like

Leave a Comment