PHP Laravel - 使用者登入與驗證實戰 - 筆記長也NotesHazuya

PHP Laravel - 使用者登入與驗證實戰

2020-06-10 21:35:01   Laravel

本篇文章是 laravel 入門系列的最後一篇文章,將會總結 Route、Controller、DB、Cookie / Session 以及 Middleware等項目來實作一個使用者登入系統,不過值得注意的是,在 laravel 中其實已經有設計好的登入架構可以使用,日後若有機會將會再寫文章介紹。

需求功能描述

設計一個使用者登入系統,具有登入表單讓使用者填寫,並送至後端與 DB 驗證,登入成功就儲存 Session,並設計一個 middleware 驗證使用者是否經登入,登入才允許瀏覽網站。

架構設計

以下的架構設計及功能非常簡單,不過應該足以練習到所有前面所提及的基本功能~

Route

Route

Method

說明

/

GET

顯示網站頁面

/login

GET

顯示登入表單畫面

/login

POST

處理登入請求

/logout

GET

處理登出請求

Controller

UserController:處理所有關於使用者的事情,如登入。

-showLoginPage() :顯示登入畫面

-login():處理登入請求

-logout():處理登出請求

PageController:處理其他頁面之呈現。

-index():顯示網站首頁。

Middleware

userAuth:驗證使用者是否登入。

View

index.blade.php:首頁。

login.blade.php:登入頁面。

DB

UserTable

UserID(PK, AI, int, 10)

UserName(varchar, 255)

PassWord(varchar, 255)

1

user

 

實作

這裡會直接放程式碼以及部分解說,建議在看解答之前可以先自己練習看看喔!

Route

首先在 web.php 上新增路由

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

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', 'PageController@index')->middleware('userAuth');

Route::post('login', 'UserController@login');

Route::get('login', 'UserController@showLoginPage');

Route::get('logout', 'UserController@logout');

記得在首頁加上中間件來驗證使用者是否已經登入。

Controller

再來設計後端的 Controller,先以指令新增

php artisan make:controller UserController

php artisan make:controller PageController

我們先編輯 PageController,建立一個 index 方法

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PageController extends Controller
{
    public function index()
    {
        $username = session('username');
        return view('index', ['username' => $username]);
    }
}

如果使用者登入了, Session 就會儲存 username,之後將 username 回傳到 index 模板。

再來編輯 UserController

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use DB;

class UserController extends Controller
{
    public function showLoginPage()
    {
        return view('login');
    }

    public function login(Request $request)
    {
        DB::connection('mysql');
        $userData = DB::select("SELECT * FROM UserTable WHERE username=?", [$request->UserName]);

        if(!isset($userData[0]->UserName)){

            return view('login', ['err'=>"使用不存在"]);

        }elseif(password_verify($request->PassWord, $userData[0]->PassWord)){

            session(['username' => $userData[0]->UserName]);
            return redirect('/');

        }else{

            return view('login', ['err'=>"密碼錯誤"]);

        }
    }

    public function logout()
    {
        session()->forget('username');
        return redirect('/');
    }
}

showLogin 部分,就很單純的回傳登入畫面。而 login 略為複雜一些,收到請求時先從資料庫查詢這個 UserName 有沒有資料,如果沒有就回傳錯誤訊息;如果有就判斷密碼是否正確,正確就寫入 Session,不正確就回傳錯誤訊息。logout 部分就清除 Session 即可。

password_verify():為了避免密碼外洩,因此會將密碼雜湊。 PHP 提供了這個函式來驗證密碼。

Middleware

namespace App\Http\Middleware;

use Closure;

class userAuth
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if(!session('username')){
            return redirect('/login');
        }
        return $next($request);
    }
}

中間件部分很簡單,單純驗證使用者是否已經登入,已經登入就允許請求,否則重新導向至登入頁面。

記得在 /app/Http/Kernel.php 將中間件向應用程式註冊

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        'userAuth' => \App\Http\Middleware\userAuth::class
    ];

View

模板部分我們有兩個,首先是登入部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>登入</h1>
    @if(isset($err))
    {{ $err }}
    @endif
    <form action="login" method="post">
    <input name="UserName" type="text">
    <input name="PassWord" type="password">
    <input type="submit" value="登入">
    <input type="hidden" name="_token" value="{{ csrf_token() }}">
    </from>
</body>
</html>

很簡單,只有兩個欄位以及一個按鈕,並記得加入 csrf_token 的部分。if 部分,如果 Controller 回傳錯誤則印出錯誤。

首頁模板部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
</head>
<body>
    <h1>您好,{{ $username }}</h1>
    <p><a href=""logout"登出></a></p>
</body>
</html>

模板部分很簡單,就輸出使用者名稱以及登出路徑而已。

結果

如果上面步驟都沒有問題,應該可以做出一個很陽春的登入系統owo

登入畫面

如果密碼或是帳號有錯誤

登入成功之後會被導到首頁

登出之後會被重新導到登入畫面,如果你嘗試瀏覽首頁也會被導到登入頁面。

結論及結語

Laravel 的基本入門文章到此應該就告一段落了,從基本的架構到 Middleware 為止,已經可以設計出一個具有後台基本功能的網站了~希望對於想入門的各位有些幫助!我們後會有期~~


長也

我只專注做好自己能做的事情,別人要做什麼我無法干涉。