利用Laravel自帶的驗證機制,來實現帳密登入.忘記密碼等功能
登入路徑 /login
註冊路徑 /register
Laravel 5
Step 1.開啟Terminal,輸入 php artisan make:auth
Step 2.Laravel會自動生出所需要的視圖與路由規則
Laravel 6~7
前台改用vue,所以方法有變
Step 1.下載laravel/ui套件後生成所需視圖與規則,開啟Terminal,輸入以下指令:
composer require laravel/ui
php artisan ui vue –auth
Step 2.編譯js檔案,開啟Terminal,輸入以下指令
npm install
npm run dev
Laravel 8.x
改用官方套件jetstream,方法又變了
Step 1.下載laravel/jetstream套件,生成所需要的資源檔與Migration
composer require laravel/jetstream
php artisan jetstream:install livewire
Step 2.編譯js檔案,開啟Terminal,輸入以下指令
npm install
npm run dev
PS:需先安裝npm工具
Step 1.下載NVM安裝檔,它可以幫我們安裝npm和node
Step 2.開啟Terminal,執行npm -v 以確認是否安裝成功
如果您正在生成一個全新的應用程式,並且希望包含身份驗證框架,則可以在創建應用程式時使用 –jet 指令。 此命令將創建一個新的應用程式,並編譯安裝所有身份驗證框架:
laravel new 專案名稱 --jet
//app/Http/Controllers/Auth/LoginController.php
//改用auth/login2.blade.php作為登入頁面
public function showLoginForm()
{
return view('auth.login2');
}
//app/Http/Controllers/Auth/RegisterController.php
//改用auth/register2.blade.php作為註冊頁面
public function showRegistrationForm()
{
return view('auth.register2');
}
//app/Http/Controllers/Auth/LoginController.php
protected $redirectTo = '/home'; //登入後轉址到/home
//函式版本的優先級較高,可根據邏輯決定導到哪個網址
public function redirectTo(){
if(Auth::user()->role_id == 2){
//假如是一般使用者
return '/home';
}else if(Auth::user()->role_id == 1){
//假如是管理員
return '/admin';
}else{
return '/login';
}
}
//app/Http/Controllers/Auth/LoginController.php
use Illuminate\Http\Request;
//設定登出網址
protected function loggedOut(Request $request)
{
return redirect('/my/logout/path');
}
Step 0.users表格內建沒有username欄位,先修改migration後更新表格,然後加入資料
Step 1.在 app/Http/Controllers/Auth/LoginController.php 加入username()
//app/Http/Controllers/Auth/LoginController.php
public function username(){
return 'username';
}
提醒:請注意App\User.php的$fillable白名單屬性有加上username,否則會無法寫入此欄位
Step 2.修改登入視圖
將email部分的內容改成帳號
//resources/views/auth/login.blade.php
<div class="form-group row">
<label for="username" class="col-md-4 col-form-label text-md-right">帳號</label>
<div class="col-md-6">
<input id="username" type="username" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autocomplete="username" autofocus>
@error('username')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
Step 1.修改註冊頁面,加入帳號欄位的輸入項
<div class="form-group row">
<label for="username" class="col-md-4 col-form-label text-md-right">帳號</label>
<div class="col-md-6">
<input id="username" type="text" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autocomplete="username" autofocus>
@error('username')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
Step 2.修改users表格的migration檔案,加入所需要的欄位
Step 3.修改Model類別 User的$fillable屬性,加入新欄位
Step 4.修改RegisterController.php控制器的validator()和create()
\\app\Http\Controllers\RegisterController.php
//這個方法負責註冊表單的驗證
protected function validator(array $data)
{
return Validator::make($data, [
'username' => ['required', 'string', 'max:255'],
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
//這個方法負責將註冊表單的資料寫入資料庫
protected function create(array $data)
{
return User::create([
'username' => $data['username'],
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
Step 1.生成Notification檔案,指令如下
php artisan make:notification PasswordReset
Step 2.編輯PasswordReset.php
//app/Notifications/PasswordReset.php
public $token;
public function __construct($token)
{
$this->token = $token;
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('Email主旨')
->line('重設密碼訊息第一行')
->action('重設密碼', url('password/reset',$this->token))
->line('重設密碼第二行');
}
Step 3.修改 User Model,加入以下內容:
//app/User.php;
public function sendPasswordResetNotificatoin($token){
$this->notify(new ReminderNotification($token));
}
PS:需載入Notifiable Class,否則會出現以下錯誤 Call to undefined method,作法如下:
…
use Illuminate\Notifications\Notifiable;
use App\Notifications\PasswordReset;
class User extends Authenticatable
{
use Notifiable;
}
Step 4.複寫視圖 Layout,需複寫原始視圖到 resources資料夾,指令如下:
php artisan vendor:publish
編輯視圖檔 /resources/views/vendor/notifications
如前所述,laravel/jetstream套件的 php artisan jetstream:install 命令將創建驗證所需的所有視圖,並將它們放在 resources/views/auth 的資料夾底下。
Jetstream 還將創建一個 resources/views/layouts 資料夾,其中包含應用程式的基本布局。這些驗證視圖都使用 Tailwind CSS 框架,但是你可以按你的意願自由地客製它們。
如果樣式表沒抓到導致跑版,請修改resources/views/layouts/guest.blade.php
也可修改mix-manifest.json,在路徑前面加個.
修改resources/views/login.blade.php
Step 1.修改resources/views/register.blade.php
Step 2.修改app/Fortify/CreateNewUser.php
Step 3.修改app/Models/User.php
修改app/Providers/RouteServiceProvider.php,改動如下:
public const HOME = '/登入後轉址路徑'
Step 1.在app\Responses資料夾內加入以下檔案
Responses資料夾可能不存在,需要自己新增
<?php
namespace App\Responses;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
class LogoutResponse implements LogoutResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 204)
: redirect('/logout'); //登出時轉址路徑
}
}
Step 2.在app/Providers/FortifyServiceProvider.php加入以下內容
use App\Responses\LogoutResponse;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
...
public function register()
{
$this->app->bind(
LogoutResponseContract::class,
LogoutResponse::class
);
}
Step 1.修改resources/views/login.blade.php,將email欄位改為username
Step 2.修改config/fortify.php,將'username'的值改為username
Step 1.修改resources/views/register.blade.php
Step 2.修改app/Fortify/CreateNewUser.php
Step 3.修改app/Models/User.php
修改app/Http/Middleware/Authenticate.php的redirectTo()
取得登入用戶
範例碼
public function who(Request $request)
{
//取得登入用戶
dd(Auth::user()->id);
//取得登入用戶主鍵
dd(Auth::id());
//取得登入用戶
dd($request->user());
}
用程式進行登入
範例碼
public function selflogin()
{
$user = User::findOrFail(13);
Auth::login($user);
}
用程式進行登出
範例碼
public function logout()
{
Auth::logout();
}
確認是否完成登入
範例碼
public function checkAuth()
{
dd(Auth::check());
}
透過Controller建構子來設定
public function __construct(){
//這個控制器的所有方法都需要通過驗證
$this->middleware('auth');
}
要加入內建的驗證路由,只需要在web.php加入以下規則即可。也可透過php artisan make:auth指令生成
Auth::routes()
如需要移除註冊功能的具體作法
Step 1.刪除RegisterController.php
Step 2.修改驗證路由如下
Auth::routes(['register'=>'false']);
方法1 在路由後面加上middleware('auth');
\\routes\web.php
//需要驗證才能訪問的路由
Route::get('/home', 'HomeController@index')->middleware('auth');
方法2 在路由群組加上 middleware for auth
\\routes\web.php
Route::group(['middleware' => 'auth'], function() {
//需要驗證才能訪問的路由
Route::get('/home', 'HomeController@index');
});
用於沒有登入頁面可用時,會跳出輸入使用者名稱和密碼的popup視窗,請在使用者名稱輸入email
\\routes\web.php
Route::group(['middleware' => 'auth.basic'], function() {
//需要驗證才能訪問的路由
Route::get('/home', 'HomeController@index');
});
找到app\Http\Middleware\Authenicate.php後實作redirectTo()
範例碼
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
//如果未登入則轉址到/403
return '/403';
}
}
從 vendor/tcg/voyager/resources/views/login.blade.php
複製到 resources/views/vendor/voyager/login.blade.php
將此login.blade.php的email輸入項改為username
範例碼
<div class="form-group form-group-default" id="usernameGroup">
<label>帳號</label>
<div class="controls">
<input type="text" name="username" id="username" value="{{ old('username') }}" placeholder="請輸入帳號" class="form-control" required>
</div>
</div>
Step 2.修改voyager.php的namespace設定,指向到自己的專案
//config/voyager.php
'controllers' => [
//'namespace' => 'TCG\\Voyager\\Http\\Controllers',
'namespace' => 'App\\Http\\Controllers\\Voyager',
],
Step 3.將所有Voyager控制器複製一份到自己的專案,路徑在App\Http\Controllers\Voyager
開啟Terminal,輸入以下指令
php artisan voyager:controller
出現以下錯誤,表示Step2並沒有完成
The controllers namespace must start with your application namespace: App</error>
Step 4.在VoyagerAuthController.php加入username(),回傳username
\\App\\Http\\Controllers\Voyager\\VoyagerAuthController.php
public function username(){
return 'username';
}
原因是因為檔案的網址路徑出現錯誤,只需要告訴它livewire檔案的正確網址即可
Step 1.開啟Terminal,輸入以下指令
php artisan vendor:publish --tag=livewire:config
Step 2.修改config/livewire.php,將asset_url改成正確的網址路徑
'asset_url' => 'http://localhost:6080/form/public',
原因是使用XAMPP,網址路徑問題導致表單指向的路徑不正確導致,解法是修改成resources/views/auth/two-factor-challenge.blade.php的以下內容
line 18
<form method="POST" action="{{ url('/two-factor-challenge') }}">