實作Laravel 註冊、登入搭配JWT

更新於 發佈於 閱讀時間約 29 分鐘

本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。

發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。

會員註冊設計

我們將用vite編譯工具來幫我們產生JS and CSS,詳細配置可以看一下先前的文章。 實作 Laravel 9 改用 vite 作為前端編譯檔案配置

首先先設計註冊畫面,創建一個命名為signUp.blade.php,附上範例code

@extends('layouts.app') 
@section('content')
<div class="row d-flex justify-content-center align-items-center h-100 vh-100">
<div class="col-12 col-md-8 col-lg-6 col-xl-5">
<div class="card shadow-2-strong" style="border-radius: 1rem;">
<div class="card-body p-5">
<form method="POST" action="{{ route('register') }}">
@csrf
<h3 class="mb-5 text-center">會員註冊</h3>

<div class="form-outline mb-4">
<label for="account" class="form-label">會員帳號</label>
<input
id="account"
type="text"
class="form-control form-control-lg"
placeholder="Account"
aria-label="Account"
aria-describedby="basic-addon1"
name="account"
/>
</div>

<div class="form-outline mb-4">
<label for="userName" class="form-label">會員名稱</label>
<input
id="userName"
type="text"
class="form-control form-control-lg"
placeholder="UserName"
aria-label="userName"
aria-describedby="basic-addon1"
name="userName"
/>
</div>

<div class="form-outline mb-4">
<label for="password" class="form-label">會員密碼</label>
<input
id="password"
type="password"
id="password"
class="form-control form-control-lg"
placeholder="Password"
aria-label="Password"
aria-describedby="basic-addon1"
name="password"
/>
</div>

<div class="form-outline mb-4">
<label for="password-confirm" class="form-label">確認密碼</label>
<input
id="password-confirm"
type="password"
class="form-control form-control-lg"
name="password_confirmation"
required
autocomplete="new-password"
placeholder="PasswordConfirm"
/>
</div>

<!-- button -->
<div class="d-grid gap-2">
<button class="btn btn-primary btn-lg" type="submit">
REGISTER
</button>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection

畫面長這樣(很簡陋的東西XDDDD)

raw-image

接著撰寫Controller邏輯

php artisan make:controller AuthController​

編寫取得signUp.blade.php View跟註冊 register邏輯方法

註:這邊function命名方式採用camelCase,駝峰命名方式,又稱小駝峰命名方式(lowerCamelCase)

<?php

namespace App\Http\Controllers;

use Exception;
use App\Models\User;
use Illuminate\Support\Str;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests\RegisterRequest;

class AuthController extends Controller
{
public function signUp()
{
return view('signUp');
}

public function register(RegisterRequest $request)
{
$uid = Str::uuid();
$account = $request->request->get('account');
$userName = $request->request->get('userName');
$password = $request->request->get('password');

User::create([
'uid' => $uid,
'account' => $account,
'userName' => $userName,
'password' => bcrypt($password),
]);

return redirect()->route('signIn');
}
}

這邊的Request改採用Form Request來編寫,方便以後寫特定的Rules。

php artisan make:request RegisterRequest
raw-image

再來修改原本的migration table User Table的部分,修改部分為綠色code的樣子,主要是我的id想要用成uid的方式,email改為允許為null,主鍵改成uid,配置完成執行migrate

php artisan migrate
raw-image

接著配置User Model

<?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;

protected $primaryKey = 'uid';
protected $keyType = 'string';

protected $guarded = [];

/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'uid',
'userName',
'account',
'email',
'password',
];

/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];

/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}

配置路由web.php檔案,而路由檔支持的寫法有很多種,詳下圖

raw-image

接下來確認新增都沒問題就大功完成註冊的部分~

raw-image

會員登入設計

會員登入的畫面拿註冊畫面來改,一樣先創建signIn.blade.php畫面

@extends('layouts.app')

@section('content')
<div class="row d-flex justify-content-center align-items-center h-100 vh-100">
<div class="col-12 col-md-8 col-lg-6 col-xl-5">
<div class="card shadow-2-strong" style="border-radius: 1rem;">
<div class="card-body p-5">
<form action="{{ route('login') }}" method="post" enctype="multipart/form-data">
@csrf
<h3 class="mb-5 text-center">LOGIN</h3>

<div class="form-outline mb-4">
<label for="account" class="form-label">會員帳號</label>
<input id="account" type="text" class="form-control form-control-lg" placeholder="Account"
aria-label="Account" aria-describedby="basic-addon1" name="account">
</div>

<div class="form-outline mb-4">
<label for="password" class="form-label">會員密碼</label>
<input id="password" type="password" id="password" class="form-control form-control-lg"
placeholder="Password" aria-label="Password" aria-describedby="basic-addon1" name="password">
</div>

<!-- Checkbox -->
{{-- <div class="form-check d-flex justify-content-start mb-4">
<input class="form-check-input" type="checkbox" value="" id="form1Example3" />
<label class="form-check-label" for="form1Example3"> Remember password </label>
</div> --}}


<!-- button -->
<div class="d-grid gap-2">
<a type="submit" id="create_form" class="btn btn-primary btn-lg">Login</a>
{{-- <button class="btn btn-primary btn-lg" type="submit" id="create_form">Login</button> --}}
<hr class="my-2">
<button class="btn btn-lg btn-block btn-primary" style="background-color: #dd4b39;"
type="submit"><i class="fab fa-google me-2"></i> Sign in with google</button>
<hr class="my-2">
<button class="btn btn-lg btn-block btn-primary mb-2" style="background-color: #3b5998;"
type="submit"><i class="fab fa-facebook-f me-2"></i>Sign in with facebook</button>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection




安裝JWT並產生Token

這邊使用tymon/jwt-auth 套件,並根據使用文檔配置,來設定我們的Private Key,並搭配 firebase/php-jwt,來創建我們的Token

composer require tymon/jwt-auth

配置vendor,接著會產生config/jwt.php檔案,有些設定可以在這邊改

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"

產生金鑰

php artisan jwt:secret

安裝firebase/php-jwt

composer require firebase/php-jwt

接著開始寫產生Token的程式邏輯,這邊創建Services/AuthService.php 檔案,並定義一個encode方法

raw-image

接著修改AuthController檔案,增加login方法,驗證登入帳密及產生Token,並由Service端把token塞到cookie,方便前端取用。

Token在前端保存有多種方式,額外再寫一篇補充說明,看完一些文件說明,大致上沒有一定需要怎麼做🧐

<?php

namespace App\Http\Controllers;

use Exception;
use App\Models\User;
use Illuminate\Support\Str;
use App\Services\AuthService;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests\RegisterRequest;

class AuthController extends Controller
{
private AuthService $authService;

public function __construct(
AuthService $authService
) {
$this->authService = $authService;
}

public function signUp()
{
return view('signUp');
}

public function signIn()
{
return view('signIn');
}

public function register(RegisterRequest $request)
{
$uid = Str::uuid();
$account = $request->request->get('account');
$userName = $request->request->get('userName');
$password = $request->request->get('password');

User::create([
'uid' => $uid,
'account' => $account,
'userName' => $userName,
'password' => bcrypt($password),
]);

return redirect()->route('signIn');
}

public function login(LoginRequest $request)
{
$account = $request->request->get('account');
$password = $request->request->get('password');

$userData = User::where('account', $account)->first();

if (!$userData || !Hash::check($password, $userData->password)) {
throw new Exception('密碼錯誤');
}

$token = $this->authService->encode($userData);

$minutes = 5;
return response()->json([
'status' => 'success',
'data' => [
'access_token' => $token,
'token_type' => 'bearer',
'expired_at' => now()->addMinutes(config('jwt.ttl'))->timestamp
]
])->withCookie(cookie('token', $token, $minutes));
}

}

新增login.js檔案,並使用AJAX處理,在登入成功確認response的結果是否有Token。

raw-image

接著測試登入結果有正常取得Token結果

raw-image
raw-image


















avatar-img
15會員
37內容數
學涯無止境,透過每日or每週模仿學習筆記,不管是哪些領域也好,總有一天也可以從菜雞變小雞
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
# 簡介 身為一位專注於 Vue.js 的前端開發者,這是我第一次嘗試構建 Flutter 網頁應用。讓我們開始吧! ## 第一次嘗試 ### 第一步:創建一個 Flutter 應用 首先,通過運行以下命令來創建一個新的 Flutter 項目: ```sh flutter
<template> <div id="charge"> <el-card class="box-card"> <ul class="msg-box"> <li> <h4>充值</h4> </li> <li>
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
這一集用最新的Vite工具去創建初始檔案。Vite用於創建和構建Web應用程序,具有快速的啟動時間、即時熱更新、小型體積、支持多種框架和可擴展性等優點。
Thumbnail
有的時候,會希望在物件導向中對原生的Class新增功能的時候,大多我們都會寫一個新的class並繼承。 但是其實Laravel提供了一個不同的方式,讓我們可以在常用的Class上,直接新增想要的function,那就是macro。
Thumbnail
Vue 是尤雨溪所開發的一個前端框架,Vue 提供了響應式數據綁定和組件化的開發模式,能方便開發者構建出具有良好交互性的前端應用。而 Vite 則是一個前端構建工具,用途是提供更快的開發體驗。然後,本文將介紹如何使用 Vite 建立一個 Vue 專案的開發環境,這是你學習 Vue 的第一步。
Thumbnail
本文探討會員系統網頁設計的技巧和策略,包括註冊和登錄流程設計、個人化的會員資料頁面、會員等級和權益設計、會員專區和互動功能、客戶支持和反饋機制等。
Thumbnail
第一份正職工作 在iot公司擔任後端工程師,一上工就使用先前沒用過的php/laravel,也馬上負責公司產品的架構規劃,先前資料庫只有簡單記載使用者跟使用者的一些設定,很多地方有資料不一致的問題,產品內容還有很多實體的關係沒有被定義進資料庫都是這次改版我要做的事情。 改版納入公司、機器
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
一開始你先把你的專案push上去後,修改vite.config.ts ,要在裡面新增  base: "/Cart/" (/放自己的專案名稱/) build: {outDir: "docs"}, 接下來你要去你的github setting 裡面 -> Page ->選Deploy fro
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
# 簡介 身為一位專注於 Vue.js 的前端開發者,這是我第一次嘗試構建 Flutter 網頁應用。讓我們開始吧! ## 第一次嘗試 ### 第一步:創建一個 Flutter 應用 首先,通過運行以下命令來創建一個新的 Flutter 項目: ```sh flutter
<template> <div id="charge"> <el-card class="box-card"> <ul class="msg-box"> <li> <h4>充值</h4> </li> <li>
Thumbnail
本文介紹如何使用Vite建立前端開發初始檔案,並加入Tailwindcss的教學。透過指令和配置檔,讓你能快速建立個人專案的開發環境,並學習如何加入全域的Tailwindcss樣式。還有影片教學、資源連結和更多相關教學文章等,幫助你進一步學習。
Thumbnail
這一集用最新的Vite工具去創建初始檔案。Vite用於創建和構建Web應用程序,具有快速的啟動時間、即時熱更新、小型體積、支持多種框架和可擴展性等優點。
Thumbnail
有的時候,會希望在物件導向中對原生的Class新增功能的時候,大多我們都會寫一個新的class並繼承。 但是其實Laravel提供了一個不同的方式,讓我們可以在常用的Class上,直接新增想要的function,那就是macro。
Thumbnail
Vue 是尤雨溪所開發的一個前端框架,Vue 提供了響應式數據綁定和組件化的開發模式,能方便開發者構建出具有良好交互性的前端應用。而 Vite 則是一個前端構建工具,用途是提供更快的開發體驗。然後,本文將介紹如何使用 Vite 建立一個 Vue 專案的開發環境,這是你學習 Vue 的第一步。
Thumbnail
本文探討會員系統網頁設計的技巧和策略,包括註冊和登錄流程設計、個人化的會員資料頁面、會員等級和權益設計、會員專區和互動功能、客戶支持和反饋機制等。
Thumbnail
第一份正職工作 在iot公司擔任後端工程師,一上工就使用先前沒用過的php/laravel,也馬上負責公司產品的架構規劃,先前資料庫只有簡單記載使用者跟使用者的一些設定,很多地方有資料不一致的問題,產品內容還有很多實體的關係沒有被定義進資料庫都是這次改版我要做的事情。 改版納入公司、機器