Laravel 經過 Passport 實現 API 請求認證:基於 Cookie 的同域名應用篇

同域名應用能夠使用框架自帶的登陸頁面(基於Session)實現登陸,登陸成功後使用laravel_token(基於Cookie)實現 API 請求認證。php

安裝 & 初始化

composer require laravel/passport
php artisan migrate
# 執行 passport 的安裝過程
php artisan passport:install
  1. 在 storage 目錄下生成 oauth-private.keyoauth-public.key,分別爲 OAuth 服務的私鑰和公鑰,用於安全令牌的加密解密。
  2. oauth_clients 數據表中初始化兩條記錄,至關於註冊兩個客戶端應用,一個用於密碼受權令牌認證,一個用於私人訪問令牌認證。

修改模型類

use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    # 該 Trait 中包含了受權令牌與客戶端的相關方法
    use HasApiTokens, Notifiable;
    ...
}

註冊 API 認證相關路由

use Laravel\Passport\Passport;

public function boot()
{
    // API 認證路由註冊
    Passport::routes();
}

默認提供的路由控制器位於 \Laravel\Passport\Http\Controllers 命名空間下,而且路由前綴爲 /oauthlaravel

修改配置文件

修改配置文件 config/auth.php,將 API 認證驅動由 token 修改成 passportweb

'guards' => [
    ...
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

單頁面應用 API 認證

若是 API 認證只用於客戶端 JavaScript 與後端接口的交互,好比同域名應用,不必走複雜的跳轉受權流程,能夠在 App\Http\Kernel$middlewareGroups 中新增一個 CreateFreshApiToken 中間件來實現:數據庫

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
        \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
    ],
];

該中間件註冊在 web 路由中,當用戶經過 Web 頁面登陸後會在 Cookie 中設置一個 Token,後續客戶端發送請求時就會在 Cookie 中自動帶上這個 Token。後端

在訪問須要認證的 API 接口時,會走 auth:api 認證中間件,由於咱們在配置文件 config/auth.php 中配置的 API 認證驅動是 passport,在 Laravel 框架底層,根據中間件傳入的參數 api ,針對 API 接口認證會經過 Laravel\Passport\Guards\TokenGuard 獲取認證信息:api

public function user(Request $request)
{
    if ($request->bearerToken()) {
        return $this->authenticateViaBearerToken($request);
    } elseif ($request->cookie(Passport::cookie())) {
        return $this->authenticateViaCookie($request);
    }
}

若是請求頭中包含 Bearer Authentication 請求頭,則獲取對應的請求頭 Token 信息,不然從 Cookie 中獲取名爲 laravel_token 的 Token 信息,因爲在保存這個 Token 的時候包含了用戶ID,因此能夠提取其中的用戶 ID 從數據庫獲取用戶數據並返回,從而完成用戶認證判斷和信息獲取。瀏覽器

測試單頁面應用 API 認證

Laravel 框架默認在 routes/api.php 中提供了一個認證 API 路由,能夠基於這個路由進行測試:安全

// 爲了方便測試,先忽略 CSRF 校驗
\Laravel\Passport\Passport::$ignoreCsrfToken = true;

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

在瀏覽器中訪問這個 API 接口,因爲沒有登陸,會跳轉到登陸表單。登陸完成後,就能夠經過 http://blog.test/api/user 獲取用戶信息了。cookie

經過瀏覽器開發者工具,在「Network」中查看請求 Cookie 數據就能夠看到 laravel_token 的信息。composer

相關文章
相關標籤/搜索