Laravel - Security - Authentication

# 前言

學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 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 Authentication 中, 當我使用 CLI 來達成 Authentication Quickstart 時, 如果我沒用到 registration, 在以下 example 中可以怎麼做來移除 RegisterController
  • Example:

    <?php
    Auth::routes(這裏是?);
  • Answer:

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


# Creating Applications Including Authentication

Laravel Authentication 中, 如果我要在建立新的專案時, 一同建立 authentication scaffolding, 可以使用哪個 CLI?
laravel new projectName --auth


# 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

Laravel Authentication 中, 當我使用 authentication scaffolding 時, 預設驗證成功的使用會被導向 /home URI, 如果我要重新定義成 /yourHome, 那該在 RouteServiceProvider 如何定義, 如下 example?
  • Example:

    <?php
    public const 這裏是? = '/yourHome';
  • Answer:

    <?php
    public const HOME = '/yourHome';
以下的 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

Laravel Authentication 中, 當我使用 authentication scaffolding 時, 預設驗證成功的使用會被導向 /home URI, 如果我想要更靈活的定義 authenticated 之後要做些什麼事, 我可以在 RouteServiceProvider 帶入 authenticated method 哪些參數, 如下 example?
  • Example:

    <?php
    protected function authenticated(這裏是?)
    {
    return response([
    //
    ]);
    }
  • Answer:

    <?php
    protected function authenticated(Request $request, $user)
    {
    return response([
    //
    ]);
    }


# Username Customization

以下的 Laravel example code 的意思是?
  • Example:

    <?php
    public function username()
    {
    return 'name';
    }
  • Answer:
    當使用 Laravel Authentication scaffolding 時, 會使用 email 以及 password 欄位作為預設驗證欄位, 可使用 LoginController 中的 username(), 將 email 變更為任何你自訂的欄位


# Guard Customization

Laravel Authentication Scaffolding 中, 如果我要自定義 guard, 可以在 LoginController, RegisterController, 以及 ResetPasswordController 當中使用 哪一個 method, 如下 example?
  • Example:

    <?php
    use Illuminate\Support\Facades\Auth;

    protected function 這裏是?()
    {
    return Auth::guard('guard-name');
    }
  • Answer:

    <?php
    use Illuminate\Support\Facades\Auth;

    protected function guard()
    {
    return Auth::guard('guard-name');
    }


# Validation / Storage Customization

Laravel Authentication Scaffolding 中, 如果我要自定義註冊會員需要哪些資料, 驗證的 rule, 可以在 RegisterController 中的 哪一個 method 定義?

validator method

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'],
]);
}

Laravel Authentication Scaffolding 中, 如果我要自定義註冊會員時該如何將資料存到 database, 可以使用 RegisterController 中的 哪一個 method

create method

protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}


# Retrieving The Authenticated User

Laravel Authentication 中, 哪三種方法可以取得 authenticated user?
  • auth()->user()
  • Auth::user()
  • $request->user()


# Determining If The Current User Is Authenticated

Laravel Authentication 中, 如果我要驗證 current user 是否 authenticated (將回傳 boolean), 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    use Illuminate\Support\Facades\Auth;

    if (這裏是?) {
    // The user is logged in...
    }
  • Answer:

    <?php
    use Illuminate\Support\Facades\Auth;

    if (Auth::check()) {
    // The user is logged in...
    }


# Protecting Routes

Laravel Authentication 中, 在以下的 example 中如果要使用 auth middleware, 可以怎麼做?
  • Example:

    <?php
    Route::get('profile', function () {
    // Only authenticated users may enter...
    })->middleware('這裏是?');
  • Answer:

    <?php
    Route::get('profile', function () {
    // Only authenticated users may enter...
    })->middleware('auth');
以下的 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 Authentication 中, 在以下的 controller example 中, 如果我要使用 auth middleware 的 api guard, 可以怎麼做?
  • Example:

    <?php
    public function __construct()
    {
    $this->middleware(這裏是?);
    }
  • Answer:

    <?php
    public function __construct()
    {
    $this->middleware('auth: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 Authentication 中, 如果我要 authenticate 使用者, 在以下的 example 中可以怎麼做?
  • 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 (這裏是?) {
    // Authentication passed...
    return redirect()->intended('dashboard');
    }
    }
    }
  • Answer:

    <?php
    namespace App\Http\Controllers;

    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;

    class LoginController extends Controller
    {
    /**
    * Handle an authentication attempt.
    *
    * @param \Illuminate\Http\Request $request
    *
    * @return Response
    */
    public function authenticate(Request $request)
    {
    $credentials = $request->only('email', 'password');

    if (Auth::attempt($credentials)) {
    // Authentication passed...
    return redirect()->intended('dashboard');
    }
    }
    }
Laravel Authentication 中, Auth::attempt() method 除了 username 以及 password 之外, 還可以接受其他參數嗎?

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

Laravel Authentication 中, 以下的 intended method 的作用是?
  • 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:
    將 user 導向他原本請求的 URI


# Specifying Additional Conditions

Laravel Authentication 中, 當我使用 Auth::attempt() method 時, 如果說除了 email 跟 password 之外, 我還想驗證 active 是否為 true, 在以下的 example 中可以怎麼做?
  • Example:

    <?php
    if (Auth::attempt(['email' => $email, 'password' => $password, 這裏是?])) {
    // The user is active, not suspended, and exists.
    }
  • Answer:

    <?php
    if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
    // The user is active, not suspended, and exists.
    }


# Accessing Specific Guard Instances

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

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

Laravel Authentication 中, 當我要特別指定 guard 時, 假設我想要使用 guard admin, 以下的 example 中, 該怎麼做?
  • Example:

    <?php
    if (這裡是?->attempt($credentials)) {
    //
    }
  • Answer:

    <?php
    if (Auth::guard('admin')->attempt($credentials)) {
    //
    }


# Logging Out

Laravel Authentication 中, 如果我要登出使用者, 可以怎麼做?
<?php
Auth::logout();




# Remembering Users

Laravel Authentication 中, 當我使用 web route 時, 如果我想要使用 記住我 的功能, 在以下的 example 中, 可以怎麼做?
  • Example:

    <?php
    if (Auth::attempt(['email' => $email, 'password' => $password], 這裡是?)) {
    // The user is being remembered...
    }
  • Answer:

    <?php
    if (Auth::attempt(['email' => $email, 'password' => $password], boolean)) {
    // The user is being remembered...
    }
Laravel Authentication 中, 當我使用 remember me 功能時, Laravel 會在 User table 中的哪一個欄位記下 token?

remember_token

  • Example:

    <?php
    if (這裡是?) {
    //
    }
  • Answer:

    <?php
    if (Auth::viaRemember()) {
    //
    }


# Other Authentication Methods

# Authenticate A User Instance

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

Illuminate\Contracts\Auth\Authenticatable

Laravel Authentication 中, 如果我要登入一個 $user model, 並且開啟 remember_me 功能, 在以下的 example 中可以怎麼做?
  • Example:

    <?php
    // 這裡是?
  • Answer:

    <?php
    Auth::login($user, true);
Laravel Authentication 中, 如果我要使用指定的 guard admin 來登入一個 $user model, 並且開啟 remember_me 功能, 在以下的 example 中可以怎麼做?
  • Example:

    <?php
    Auth::這裡是?->login($user, true);
  • Answer:

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


# 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

  • Example:

    <?php
    namespace App\Http\Middleware;

    use Illuminate\Support\Facades\Auth;

    class AuthenticateOnceWithBasicAuth
    {

    public function handle($request, $next)
    {
    // 這裡是?
    }

    }
  • Answer:

    <?php
    namespace App\Http\Middleware;

    use Illuminate\Support\Facades\Auth;

    class AuthenticateOnceWithBasicAuth
    {

    public function handle($request, $next)
    {
    return Auth::onceBasic() ?: $next($request);
    }

    }

需要




# 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, 可以在哪個 AuthServiceProviderboot 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 Authentication 中, 如果我要使用 closure 來自定義 custom guard, 如下 example 中, 如果驗證通過的話該填入什麼?
  • 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) {
    // 這裡該 return?
    });
    }
  • Answer:

    <?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
    });
    }
Laravel Authentication 中, 如果我要使用 closure 來自定義 custom guard, 如下 example 中, 如果驗證沒通過的話該填入什麼?
  • 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) {
    // 這裡該 return?
    });
    }
  • Answer:

    <?php
    use App\User;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;

    public function boot()
    {
    $this->registerPolicies();

    Auth::viaRequest('custom-token', function ($request) {
    // null
    });
    }
Laravel Authentication 中, 如果我使用了 Auth::viaRequest method 自定義了 guard 如下, 在以下的 example 中, 該填入什麼
  • Guard:

    <?php
    use App\User;
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Auth;

    public function boot()
    {
    $this->registerPolicies();

    Auth::viaRequest('custom-token', function ($request) {
    return User::where('token', $request->token)->first();
    });
    }
  • Example:

    <?php
    'guards' => [
    'api' => [
    'driver' => '這裡該填入?',
    ],
    ],
  • Answer:
    custom-token




# 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 Authentication 中, 以下的 UserProvider contract 的作用是?
  • Example:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    public function retrieveById($identifier);
    }
  • Answer:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    // 透過 id 取得 authenticatable implementation
    public function retrieveById($identifier);
    }
Laravel Authentication 中, 以下的 UserProvider contract 的作用是?
  • Example:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    public function retrieveByToken($identifier, $token);
    }
  • Answer:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    // 透過 $identifier 以及 $token (remember_token) 取得 authenticatable implementation
    public function retrieveByToken($identifier, $token);
    }
Laravel Authentication 中, 以下的 UserProvider contract 的作用是?
  • Example:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    public function updateRememberToken(Authenticatable $user, $token);
    }
  • Answer:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    // 當使用者使用 *rmemeber_me* 功能登入, 或登出時更新 remember_token 的值
    public function updateRememberToken(Authenticatable $user, $token);
    }
Laravel Authentication 中, 以下的 UserProvider contract 的作用是?
  • Example:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    public function retrieveByCredentials(array $credentials);
    }
  • Answer:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    // 透過 $credential 來取得 authenticatable implementation
    public function retrieveByCredentials(array $credentials);
    }
Laravel Authentication 中, 以下的 UserProvider contract 的作用是?
  • Example:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    public function validateCredentials(Authenticatable $user, array $credentials);
    }
  • Answer:

    <?php

    namespace Illuminate\Contracts\Auth;

    interface UserProvider
    {
    // 驗證 $credential 並回傳 boolean
    public function validateCredentials(Authenticatable $user, array $credentials);
    }


# 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',
    ],
    ];
  • Answer:
    每一個 authentication 的動作都有其 event, 可以註冊該 event 的 listener 來做相對應的事, 例如, log

HTTP 學習筆記 Operating System Concept

留言

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×