Laravel 入門 — 使用者登入與驗證實戰

碼農思考中 / Ted
11 min readJul 21, 2023

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

需求功能描述

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

架構設計

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

Route

Controller

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

-showLoginPage() :顯示登入畫面

-login():處理登入請求

-logout():處理登出請求

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

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

Middleware

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

View

index.blade.php:首頁。

login.blade.php:登入頁面。

DB

實作

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

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 為止,已經可以設計出一個具有後台基本功能的網站了~希望對於想入門的各位有些幫助!我們後會有期~~

Originally published at https://studio-44s.tw.

--

--

碼農思考中 / Ted

全端工程師,Asp.Net MVC、PHP Laravel、ReactJS,隨手記錄各種技術、心得與設計靈感。未來規劃除程式技能外,也想往 UI/UX 設計領域發展。目前文章從舊有網站「筆記長也」搬移過來。業餘接案中:https://studio-44s.tw/