Laravel — Security — Authentication (官方文件原子化翻譯筆記)
By: Ray Lee
Tags: Authentication, Backend, Laravel, Documentation

Photo by Kylie Anderson on Unsplash

# 版本

Laravel 7.x

# 前言

我喜歡使用 Laravel 開發的感覺, 除了開發快速, 程式碼簡潔且優雅之外, Laravel 框架本身也是一個很好的學習參照物。 本篇主要將官方文件重點整理成 Q&A 的形式呈現, 原子化的概念, 這方式並不適用於每個人, 但若對你有幫助, 我會很開心。

# Introduction

# Database Considerations

Laravel Authentication 中, 在建立 database schema for App\User model 時, 務必確保 password 欄位要幾字元長？

60 characters

Laravel Authentication 中, 在建立 database schema for App\User model 時, 務必確保 remember_token 欄位要幾字元長？

100 characters

# Authentication Quickstart

# Routing

Laravel Authentication 中, 如果我要快速開始 Authentication, 可以什麼 CLI 直接安裝註冊登入功能？

composer require laravel/ui



php artisan ui vue --auth

Laravel Authentication 中, 以下 CLI 會自動產生哪一個 controller 來處理登入後的請求?

CLI:

composer require laravel/ui



php artisan ui vue --auth

Answer: HomeController

Laravel Authentication 中, 當我使用 CLI 來達成 Authentication Quickstart 時, 自動建立的 authentication controllers 會被建立在哪個 namespace 底下？

App\Http\Controllers\Auth

Laravel Authentication 中, 當我使用 CLI 來達成 Authentication Quickstart 時, 自動建立的 RegisterController 處理什麼工作？

註冊

Laravel Authentication 中, 當我使用 CLI 來達成 Authentication Quickstart 時, 自動建立的 LoginController 處理什麼工作？

登入

Laravel Authentication 中, 當我使用 CLI 來達成 Authentication Quickstart 時, 自動建立的 ForgotPasswordController 處理什麼工作？

發送 email 連結重設密碼

Laravel Authentication 中, 當我使用 CLI 來達成 Authentication Quickstart 時, 自動建立的 ResetPassword 處理什麼工作？

重設密碼

以下的 Laravel example code 的意思是？

Example:

<?php

Auth::routes(['register' => false]);

Answer: 不使用 Scaffolding 的 RegisterController

# Creating Applications Including Authentication

以下的 Laravel example code 的意思是？

Example:

laravel new projectName --auth

Answer: 建立新專案時, 一同建立 authentication scaffolding

# Views

Laravel Authentication 中, 使用 authentication scaffolding 建立的 view 會位於哪個資料夾內？

resources/views/auth

Laravel Authentication 中, 以下的 CLI 會將 base layouts 置於死地哪個資料夾中？

resources/views/layouts

# Authenticating

# Path Customization

Laravel Authentication 中, 當我使用 authentication scaffolding 時, 預設驗證成功的使用會被導向 /home URI, 如果我要重新定義成 /yourHome , 那該在哪一個檔案中定義？

RouteServiceProvider

以下位於 RouteServiceProvider 的 Laravel example code 的意思是？

Example:

<?php

public const HOME = '/yourHome';

Answer: Laravel Authentication 中, 當我使用 authentication scaffolding 時, 預設驗證成功的使用會被導向 /home URI, 可在 RouteServiceProvider 的 HOME property 定義要導向的位置

以下的 Laravel example code 的意思是？

Example:

<?php

class RouteServiceProvider extends ServiceProvider

{

protected function authenticated(Request $request, $user)

{

return response([

//

]);

}

}

Answer: 當使用 authentication scaffolding 時, 預設登入驗證成功後, user 會被導向 /home URI, 如果想要自己定義驗證成功後的行為, 可使用 RouteServiceProvider 的 authenticated method

# Username Customization

以下的 Laravel example code 的意思是?

Example:

<?php

public function username()

{

return 'name';

}

Answer: 當使用 Laravel Authentication scaffolding 時, 會使用 email 以及 password 欄位作為預設驗證欄位, 可使用 LoginController 中的 username(), 將 email 變更為任何你自訂的欄位

# Guard Customization

以下位於 Scaffolding — LoginController, RegisterController, ResetPasswordController 的 Laravel example code 的意思是？

Example:

<?php

use Illuminate\Support\Facades\Auth;



protected function guard()

{

return Auth::guard('guard-name');

}

Answer: 在這些 scaffolding controller 中定義 guard, 所以會在預設的行為中使用定義的 guard

# Validation / Storage Customization

以下位於 Authentication Scaffolding — RegisterController 的 Laravel example code 的意思是？

Example:

<?php

protected function validator(array $data)

{

return Validator::make($data, [

'name' => ['required', 'string', 'max:255'],

'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],

'password' => ['required', 'string', 'min:6', 'confirmed'],

]);

}

Answer: 當使用 Authentication Scaffolding 時, 可在 RegisterController 的 validator method 定義註冊會員時需要什麼資料, 以及驗證的 rule

以下位於 Authentication Scaffolding — RegisterController 的 Laravel example code 的意思是？

Example:

<?php

protected function create(array $data)

{

$user = User::create([

'name' => $data['name'],

'email' => $data['email'],

'password' => Hash::make($data['password']),

]);



Stats::create([

'user_id' => $user->id

]);



return $user;

}

Answer: 當使用 Authentication Scaffolding 時, 可在 RegisterController 中定義如何 create 一個 user, 資料要怎麼存

# Retrieving The Authenticated User

Laravel 中, 以下三種取得 authenticated user 的效果一樣嗎？

Example:

<?php

auth()->user()

Auth::user()

$request->user()

Answer: 一樣

# Determining If The Current User Is Authenticated

以下的 Laravel example code 的意思是？

Example:

<?php

use Illuminate\Support\Facades\Auth;



if (Auth::check()) {

// The user is logged in...

}

Answer: 判斷 current user 是否 authenticated, 回傳 boolean

# Protecting Routes

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('profile', function () {

// Only authenticated users may enter...

})->middleware('auth');

Answer: 使用 auth middleware 來驗證目標 url 為 ‘profile’ 的請求

以下的 Laravel example code 的意思是？

Example:

<?php

class PostContoller extends Controller

{

public function __construct()

{

$this->middleware('auth');

}

}

Answer: 在 PostController 當中使用 auth middleware

# Redirecting Unauthenticated Users

Laravel Authentication 中, 預設會將 unauthenticated user 重導向 login route, 如果我要自定義這個動作, 可以修改哪個檔案？

app/Http/Middleware/Authenticate.php

# Specifying A Guard

以下的 Laravel example code 的意思是？

Example:

<?php

public function __construct()

{

$this->middleware('auth:api');

}

Answer: 指定 auth middleware 的 guard 為 api, 預設有 web 跟 api

# Password Confirmation

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('/settings/security', function () {



})->middleware(['auth', 'password.confirm']);

Answer: 當 user 發 request 到這支 API 時, 除了會判斷身份是否 authenticated 之外, 還會導向特定頁面, 再次輸入密碼後方可存取該頁面

Laravel Authentication 中, 若我使用內建的 password.confirm middleware 來重新驗證密碼, 驗證過後, 預設有效時間是多長？

3 小時

Laravel Authentication 中, 若我使用內建的 password.confirm middleware 來重新驗證密碼, 驗證過後有效期限是 3 小時, 如果我要自定義這個時間, 可以在什麼地方定義？

auth.password_timeout

# Login Throttling

Laravel Authentication Scaffolding 中, 預設使用者輸入幾次帳密都錯誤, 會被 throttle 限制多久無法再登入？

1 分鐘

Laravel Authentication Scaffolding 中, throttle 會根據哪兩項資訊來判斷使用者的獨一性？

username / email

IP

# Manually Authenticating Users

以下的 Laravel example code 的意思是？

Example:

<?php

namespace App\Http\Controllers;



use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;



class LoginController extends Controller

{

public function authenticate(Request $request)

{

$credentials = $request->only('email', 'password');



if (Auth::attempt($credentials)) {

// Authentication passed...

return redirect()->intended('dashboard');

}

}

}

Answer: 使用 Auth::attempt() 來驗證 $credentials 是否正確, 如果正確的話, redirect 到 request 原本的目標 url

Laravel Authentication 中, Auth::attempt() method 除了 username 以及 password 之外, 還可以接受其他參數嗎？

可以哦, 會自動對應資料庫的 column

# Specifying Additional Conditions

以下的 Laravel example code 的意思是？

Example:

<?php

if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {

// The user is active, not suspended, and exists.

}

Answer: Auth::attempt() 除了可帶入預設 email, password 之外, 也可驗證其他 column

# Accessing Specific Guard Instances

Laravel Authentication 中, 什麼情況下, 我們可能會需要用到不同的 guard?

當我的應用同時使用不同的 authenticatable models 或 user table

以下的 Laravel example code 的意思是？

Example:

<?php

if (Auth::guard('admin')->attempt($credentials)) {

//

}

Answer: guard 預設為 api 或 web, 也可自定義 guard, example 中指定使用 guard 'admin' 來驗證

# Remembering Users

以下的 Laravel example code 的意思是？

Example:

<?php

if (Auth::attempt(['email' => $email, 'password' => $password], true)) {

// The user is being remembered...

}

Answer: 使用 Auth::attempt() 驗證, 且當使用 web route 時, 可在 arg2 帶入 true 啟動 remember_me feature, 會在 table 記下 remember_token

Laravel Authentication 中, 當我使用 remember me 功能時, Laravel 會在 User table 中的哪一個欄位記下 token?

remember_token

以下的 Laravel example code 的意思是？

Example:

<?php

if (Auth::viaRemember()) {

//

}

Answer: 判斷 user 是否經由 remember_me token authenticated

# Other Authentication Methods

# Authenticate A User Instance

Laravel Authentication 中, 如果我要登入一個 model, 該 model 必須要是哪個 class 的 implementation?

Illuminate\Contracts\Auth\Authenticatable

以下的 Laravel example code 的意思是？

Example:

<?php

Auth::login($user, true);

Answer: 使用 $user model login, 並開啟 remember_me feature

以下的 Laravel example code 的意思是？

Example:

<?php

Auth::guard('admin')->login($user, true);

Answer: 使用指定的 guard admin 來 authenticate, 使用 $user model 登入, 並開啟 remember_me feature

# Authenticate A User By ID

以下的 Laravel example code 的意思是？

Example:

<?php

Auth::loginUsingId(1, true);

Answer: 使用 User 來 login, 並且開啟 remember_me 的功能

# Authenticate A User Once

以下的 Laravel example code 的意思是？

Example:

<?php

if (Auth::once($credentials)) {

//

}

Answer: auth 過後並不會動用到 cookie 或 session 或 token, 也就是說相當於當下的 request 有效而已

# HTTP Basic Authentication

以下的 Laravel example code 的意思是？

Example:

<?php

Route::get('profile', function () {

// Only authenticated users may enter...

})->middleware('auth.basic');

Answer: 使用 HTTP Basic Authentication middleware, 這樣任何到 ‘profile’ 的 request 都會經過 HTTP Basic Authentication 驗證

Laravel Authentication 中, auth.basic middleware 預設會取哪一個 column 的值當作 username?

email

# A Note On FastCGI

Laravel Authentication 中, 當我使用 PHP FastCGI 並且想要使用 HTTP Basic Authentication 時, 需要在哪個檔案加入以下程式碼？

程式碼:

RewriteCond %{HTTP:Authorization} ^(.+)$

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Answer: .htaccess file

# Stateless HTTP Basic Authentication

以下的 Laravel example code 的意思是？

Example:

<?php

namespace App\Http\Middleware;



use Illuminate\Support\Facades\Auth;



class AuthenticateOnceWithBasicAuth

{



public function handle($request, $next)

{

return Auth::onceBasic() ?: $next($request);

}



}

Answer: 若要使用 HTTP Basic Authentication, 且不在 server 記下 session, 即關閉瀏覽器後, 使用者便需要重新登入, 那可自定義以上 middleware

# Logging out

以下的 Laravel example code 的意思是？

Example:

<?php

use Illuminate\Support\Facades\Auth;



Auth::logout();

Answer: 登出該使用者, 也就是說清除 server 上的 session 以及 token

# Invalidating Sessions On Other Devices

Laravel Authentication 中, 當用戶更改完密碼後, 我必須要讓該用戶在所有其他裝置失效, 若要做到這點, 我必須要讓哪一個內建的 middleware un-commented?

Example:

<?php

'web' => [

// ...

// 這裡是？

// ...

],

Answer:

<?php

'web' => [

// ...

\Illuminate\Session\Middleware\AuthenticateSession::class,

// ...

],

以下的 Laravel example code 的意思是？

Example:

<?php

use Illuminate\Support\Facades\Auth;



Auth::logoutOtherDevices($password);

Answer: 當 user 變更密碼之後, 可能會需要把變更密碼前的所有裝置都 logout, 這時就可以使用 logoutOtherDevices method

Laravel Authentication 中, 當用戶更改完密碼後, 我必須要讓該用戶在所有其他裝置失效, 當我啟動 AuthenticationSession middleware 來做到這點後, 如果我用來登入的 route 不是叫做 login, 那我必須要再來 exception handler 中 override 哪一個 method 來導向我設定的登入用 route?

unauthenticated method

# Social Authentication

# Adding Custom Guards

Laravel Authentication 中, 如果我要自定義 guard, 可以在哪個檔案中的 boot method 定義？

AuthServiceProvider

Laravel Authentication 中, 如果我要自定義 guard, 可以在哪個 AuthServiceProvider 的 boot method 中, 使用哪一個 method?

Auth::extend method

# Closure Request Guards

Laravel Authentication 中, 如果我要使用 closure 來自定義 custom guard, 可以在哪個檔案中的 boot method 中定義？

AuthServiceProvider

Laravel Authentication 中, 如果我要使用 closure 來自定義 custom guard, 可以在 AuthServiceProvider 中的 哪個 method 定義？

boot method

Laravel Authentication 中, 如果我要使用 closure 來自定義 custom guard, 可以在 AuthServiceProvider 中的 boot method 中使用哪個 method？

Auth::viaRequest

以下的 Laravel example code 的意思是？

Example:

<?php

use App\User;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;



public function boot()

{

$this->registerPolicies();



Auth::viaRequest('guardName', function ($request) {

return User::where('token', $request->token)->first();

});

}

Answer: 自定義一個 guard, 名為 guardName closure 內為 guard 的規則

以下的 Laravel example code 的意思是？

Example:

<?php

use App\User;

use Illuminate\Http\Request;

use Illuminate\Support\Facades\Auth;



public function boot()

{

$this->registerPolicies();



Auth::viaRequest('custom-token', function ($request) {

// User instance or null

});

}

Answer: 在 Auth Service Provider boot() 中, 使用 Auth::viaRequest 自定義一個 closure based guard, arg1 為 guard name, arg2 為驗證的 closure, 若驗證通過則 return user instance, 若否則為 null

以下位於 config/auth.php 的 Laravel example code 的意思是？

Example:

<?php

'guards' => [

'api' => [

'driver' => 'custom-token',

],

],

Answer: Laravel 中, api guard 預設使用 driver 為 token, 即驗證的邏輯, 上面 example 中指定了 guard api 需使用自定義的 custom-token guard 來驗證

# Adding Custom User Providers

Laravel Authentication 中, guard 跟 provider 的差別？

guard 是 Laravel 將把 authenticated user’s detail 存在哪, 像是 session, database, etc

User provider 是 Laravel 如何 authenticate a user, 像是 Eloquent, 或 API, 或其他

Laravel Authentication 中, 如果我要自定義一個 user provider, 可以在哪個檔案中中的 boot method？

AuthServiceProvider

Laravel Authentication 中, 如果我要自定義一個 user provider, 可以在 AuthServiceProvider 中的 哪一個 method 定義？

boot method

# The User Provider Contract

Laravel Authentication 中, Illuminate\Contracts\Auth\UserProvider 的作用？

透過各種 method 從 persistent storage system 中取出並回傳一個 Illuminate\Contracts\Auth\Authenticatable implementation

以下的 Laravel example code 的意思是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface UserProvider

{

public function retrieveById($identifier);

}

Answer: 透過 id 取得 authenticatable implementation

Laravel Authentication 中, 以下的 UserProvider contract 的作用是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface UserProvider

{

public function retrieveByToken($identifier, $token);

}

Answer: 透過 $identifier 以及 $token (remember_token) 取得 authenticatable implementation

Laravel Authentication 中, 以下的 UserProvider contract 的作用是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface UserProvider

{

public function updateRememberToken(Authenticatable $user, $token);

}

Answer: 當使用者使用 rmemeber_me 功能登入, 或登出時更新 remember_token 的值

Laravel Authentication 中, 以下的 UserProvider contract 的作用是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface UserProvider

{

public function retrieveByCredentials(array $credentials);

}

Answer: 透過 $credential 來取得 authenticatable implementation

Laravel Authentication 中, 以下的 UserProvider contract 的作用是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface UserProvider

{

public function validateCredentials(Authenticatable $user, array $credentials);

}

Answer: 驗證 $credential 並回傳 boolean

# The Authenticatable Contract

Laravel Authentication 中, 以下的 authenticatable method 的意思是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface Authenticatable

{

public function getAuthIdentifierName();

}

Answer: 取得 primary key 的欄位名稱

Laravel Authentication 中, 以下的 authenticatable method 的意思是？

Example:

<?php



namespace Illuminate\Contracts\Auth;



interface Authenticatable

{

public function getAuthIdentifier();

}

Answer: 取得 primary key 欄位的 值

# Events

Laravel Authentication 中, 以下的 example 的用途是？

Example:

<?php

protected $listen = [

'Illuminate\Auth\Events\Registered' => [

'App\Listeners\LogRegisteredUser',

],



'Illuminate\Auth\Events\Attempting' => [

'App\Listeners\LogAuthenticationAttempt',

],



'Illuminate\Auth\Events\Authenticated' => [

'App\Listeners\LogAuthenticated',

],



'Illuminate\Auth\Events\Login' => [

'App\Listeners\LogSuccessfulLogin',

],



'Illuminate\Auth\Events\Failed' => [

'App\Listeners\LogFailedLogin',

],



'Illuminate\Auth\Events\Logout' => [

'App\Listeners\LogSuccessfulLogout',

],



'Illuminate\Auth\Events\Lockout' => [

'App\Listeners\LogLockout',

],



'Illuminate\Auth\Events\PasswordReset' => [

'App\Listeners\LogPasswordReset',

],

];