今天我們來把登入的功能完成.
當驗證通過之後,
就可以正常登入,
在登入的時候,
我們會透過session來記錄會員的編號,
來作為會員已登入的驗證.
app/Http/Controllers/UserAuthController.php的signInProcess的方法
//前面省略
//session紀錄會員編號
session()->put('user_id', $User->id);
//重新導向到原先使用者造訪頁面,沒有嘗試造訪頁則重新導向回自我介紹頁
return redirect()->intended('/admin/user');
使用者在瀏覽網站的時候,
有可能會因為不同的原因而進入登入頁,
這時候如果能夠重新回到登入前的頁面,
是比較好的使用者體驗,
Laravel也考慮到了這一點,
所以提供redirect()->intended()
方法,
來處理重新導向的功能,
intended方法裡面可以放預設的頁面,
如果使用者是直接進入登入頁,
就會重新導向到指定的頁面.
在這個部落格網站裡面,
會有所謂的前台後台,
以我所認知的部落格而言,
每一個使用者的權限都是一樣的,
可以編輯屬於自己的後台,
也可能觀看所有人的前台,
當我們要觀看前台的時候不需要登入,
(但是要留言的話需要登入)
不過當我們要進入後台的話就需要驗證你是否已登入,
我們在登入完畢之後會進入到後台編輯自我介紹的部分.
所有session的設定都放在config/session.php
這個設定檔案內,
其中有一行
'driver' => env('SESSION_DRIVER', 'file'),
表示要用甚麼方法來儲存session,
Laravel有提供file
、cookie
、database
、apc
、memcached
、redis
及array
等等儲存方式,
如果只有一台主機,
大部分都使用file就可以了,
可是如果有好幾台主機,
假如沒辦法做到同步,
就會有「明明已經登入,系統卻判斷為沒有登入」的問題,
就可以使用database、redis或memchached等等的方式,
我們這裡只考慮一台主機的情況,
所以不需要修改session的設定.
所以我們要判斷是否會員已登入,
就是透過session的user_id來判斷,
我們用Laravel提供的session()->has()
方法來判斷是否已經登入.
if(session()->has('user_id'))
既然我們是透過session來判斷會員登入,
登出的時候就是透過Laravel提供的session()->forget()
方法來清除session資料,
之後再重新導向到首頁.
app/Http/Controllers/UserAhthController.php的signOut方法
//登出
public function signOut()
{
//清除Session
session()->forget('user_id');
//重新導向回首頁
return redirect('/');
}
我們之前把所有的功能都放在Menu上,
但是這樣子是很奇怪的,
如果沒有登入,
就不應該會有登出的功能,
在這裡我們分成幾種情況,
一種是尚未登入的情況,
會有部落格
、註冊
、登入
等頁籤, => 在此將原先的首頁改成部落格
一種是已登入而且在前台,
會有部落格
、進入後台
、登出
等頁籤
另外一種是已登入而且在後台,
會有自我介紹
、心情隨筆
、回到前台
等頁籤
我們把resources/views/layout/master修改如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>@yield('title')</title>
<script src="/js/app.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/css/app.css?<?php echo date("mj", time())?>">
</head>
<boby>
<div class="toolbar_section">
<span class="toolbar_title">@yield('title')</span>
<span class="toolbar_title2">小魚</span>
</div>
<div class="container">
<div class="col-sm-1 form background_white">
<ul class="nav nav-pills nav-stacked">
@if($page == "admin" && session()->has('user_id'))
<!-- 自我介紹 -->
<li
@if($name == "user")
class="active"
@endif
>
<a href="/admin/user">自我介紹</a>
</li>
<!-- 心情隨筆 -->
<li
@if($name == "mind")
class="active"
@endif
>
<a href="/admin/mind">心情隨筆</a>
</li>
<!-- 回到前台 -->
<li>
<a href="/">部落格</a>
</li>
@else
<!-- 首頁 -->
<li
@if($name == "home")
class="active"
@endif
>
<a href="/">部落格</a>
</li>
@if(session()->has('user_id'))
<!-- 自我介紹 -->
<li>
<a href="/admin/user">進入後台</a>
</li>
@else
<!-- 註冊 -->
<li
@if($name == "sign_up")
class="active"
@endif
>
<a href="/user/auth/sign-up">註冊</a>
</li>
<!-- 登入 -->
<li
@if($name == "sign_in")
class="active"
@endif
>
<a href="/user/auth/sign-in">登入</a>
</li>
@endif
@endif
@if(session()->has('user_id'))
<!-- 登出 -->
<li>
<a href="/user/auth/sign-out">登出</a>
</li>
@endif
</ul>
</div>
<div class="col-sm-11 background_white2">
@yield('content')
</div>
</div>
</body>
</html>
而routes/web.php也修改如下
<?php
use Illuminate\Support\Facades\Route;
//首頁
Route::get('/', 'HomeController@indexPage');
Route::group(['prefix' => 'user'], function(){
//使用者驗證
Route::group(['prefix' => 'auth'], function(){
//使用者註冊畫面
Route::get('/sign-up', 'UserAuthController@signUpPage');
//處理註冊資料
Route::post('/sign-up', 'UserAuthController@signUpProcess');
//使用者登入畫面
Route::get('/sign-in', 'UserAuthController@signInPage');
//處理登入資料
Route::post('/sign-in', 'UserAuthController@signInProcess');
//處理登出資料
Route::get('/sign-out', 'UserAuthController@signOut');
});
});
Route::group(['prefix' => 'admin'], function(){
//自我介紹相關
Route::group(['prefix' => 'user'], function(){
//自我介紹頁面
Route::get('/', 'AdminController@editUserPage');
//處理自我介紹資料
Route::post('/', 'UserAuthController@editUserProcess');
});
//心情隨筆相關
Route::group(['prefix' => 'mind'], function(){
//心情隨筆列表頁面
Route::get('/', 'AdminController@mindListPage');
//新增心情隨筆資料
Route::get('/add', 'AdminController@addMindPage');
//處理心情隨筆資料
Route::post('/edit', 'AdminController@editMindProcess');
//單一資料
Route::group(['prefix' => '{mind_id}'], function(){
//編輯心情隨筆資料
Route::get('/edit', 'AdminController@editMindPage');
//刪除心情隨筆資料
Route::get('/delete', 'AdminController@deleteMindProcess');
});
});
});
?>
在這裡我們新增一個變數$page來判斷是否是後台,
所以之前的Controller都要加上$page這個變數,
否則就會出錯,
我們重新修改HomeController和UserAuthController兩個檔案
app/Http/Controllers/HomeController.php
<?PHP
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Module\ShareData;
class HomeController extends Controller
{
public $page = "";
//首頁
public function indexPage()
{
$name = 'home';
$binding = [
'title' => ShareData::TITLE,
'page' => $this->page,
'name' => $name,
];
return view('home', $binding);
}
}
?>
app/Http/Controllers/UserAhthController.php
<?PHP
namespace App\Http\Controllers;
use Mail;
use Hash;
use Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use App\Module\ShareData;
use App\Entity\User;
class UserAuthController extends Controller
{
public $page = "";
//使用者註冊畫面
public function signUpPage()
{
$name = 'sign_up';
$binding = [
'title' => ShareData::TITLE,
'page' => $this->page,
'name' => $name,
];
return view('user.sign-up', $binding);
}
//處理註冊資料
public function signUpProcess()
{
//接收輸入資料
$input = request()->all();
//驗證規則
$rules = [
//暱稱
'name' => [
'required',
'max:50',
],
//帳號(E-mail)
'account' => [
'required',
'max:50',
'email',
],
//密碼
'password' => [
'required',
'min:5',
],
//密碼驗證
'password_confirm' => [
'required',
'same:password',
'min:5'
],
];
//驗證資料
$validator = Validator::make($input, $rules);
if($validator->fails())
{
//資料驗證錯誤
return redirect('/user/auth/sign-up')
->withErrors($validator)
->withInput();
}
$input['password'] = Hash::make($input['password']);
//Log::notice(print_r($input, true));
//啟用紀錄SQL語法
DB::enableQueryLog();
//新增使用者資料
User::create($input);
//取得目前使用過的SQL語法
Log::notice(print_r(DB::getQueryLog(), true));
//寄送註冊通知信
$mail_binding = [
'name' => $input['name']
];
Mail::send('email.signUpEmailNotification', $mail_binding,
function($mail) use ($input){
//收件人
$mail->to($input['account']);
//寄件人
$mail->from('henrychang0202@gmail.com');
//郵件主旨
$mail->subject('恭喜註冊Laravel部落格成功!');
});
//重新導向到登入頁
return redirect('/user/auth/sign-in');
}
//使用者登入畫面
public function signInPage()
{
$name = 'sign_in';
$binding = [
'title' => ShareData::TITLE,
'page' => $this->page,
'name' => $name,
];
return view('user.sign-in', $binding);
}
//處理登入資料
public function signInProcess()
{
//接收輸入資料
$input = request()->all();
//驗證規則
$rules = [
//帳號(E-mail)
'account' => [
'required',
'max:50',
'email',
],
//密碼
'password' => [
'required',
'min:5',
],
];
//驗證資料
$validator = Validator::make($input, $rules);
if($validator->fails())
{
//資料驗證錯誤
return redirect('/user/auth/sign-in')
->withErrors($validator)
->withInput();
}
//取得使用者資料
$User = User::where('account', $input['account'])->first();
if(!$User)
{
//帳號錯誤回傳錯誤訊息
$error_message = [
'msg' => [
'帳號輸入錯誤',
],
];
return redirect('/user/auth/sign-in')
->withErrors($error_message)
->withInput();
}
//檢查密碼是否正確
$is_password_correct = Hash::check($input['password'], $User->password);
if(!$is_password_correct)
{
//密碼錯誤回傳錯誤訊息
$error_message = [
'msg' => [
'密碼輸入錯誤',
],
];
return redirect('/user/auth/sign-in')
->withErrors($error_message)
->withInput();
}
//session紀錄會員編號
session()->put('user_id', $User->id);
//重新導向到原先使用者造訪頁面,沒有嘗試造訪頁則重新導向回自我介紹頁
return redirect()->intended('/admin/user');
}
//登出
public function signOut()
{
//清除Session
session()->forget('user_id');
//重新導向回首頁
return redirect('/');
}
}
?>
以下是未登入的畫面
以下是登入後的前台畫面
至於登入後的後台畫面明天才開始做,
不過因為登入之後會直接導到後台,
目前還沒有Controller跟頁面,
各位大大也可以嘗試根據目前所學的,
自己先做一個頁面代替,
明天再正式做新的頁面.