#### 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-6.用戶登錄(二),token驗證
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-1.工具和本地環境
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-2.啟動項目
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-3.路由、模型與數據庫操作
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-4.跨域且傳輸數據,并優化后端接口
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-5.用戶登錄(一),密碼的bcrypt(hash)加密與驗證
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-6.用戶登錄(二),token驗證
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-7.分類的模型關聯和通用CRUD接口
> 技能學習:學習使用php(tp6框架) + vue.js,開發前端全棧網站-8.使用mavoneditor(vue的markdown編輯器),并批量上傳圖片
###### 1.生成token
(1)安裝jwt包
使用composer方法:
~~~
composer require firebase/php-jwt
~~~

(2)編寫生成token方法
~~~
function setToken($password) {
$key = "aslfjhasgjgja";
$token=array(
"iss"=>$key, //簽發者 可以為空
"aud"=>'', //面象的用戶,可以為空
"iat"=>time(), //簽發時間
"nbf"=>time(), //在什么時候jwt開始生效 (這里表示簽發后立即生效)
"exp"=> time()+1*60*60*48, //token 過期時間1秒*60*60*48=兩天
"data"=>[ //加入password,后期同樣使用password進行比對
'password'=>$password,
]
);
$jwt = JWT::encode($token, $key, "HS256"); //根據參數生成了 token
return $jwt;
}
~~~

下方調用生成token的方法:

測試:

登錄生成token值:

###### 2.驗證登陸狀態
(1)將token值存入本地緩存(上篇login模板已經寫好):

檢查本地緩存:

沒問題。
(2)驗證token:
我們需要將token值存入發送請求的請求頭中,做到只要調用接口,就可以將token一并發送到后端,從而對token登陸狀態進行比對驗證。
第一步,前端admin端通過請求頭將token傳值給后端:
在http.js中全局設置獲取token,將token值傳入請求頭Request
Headers中,然后后臺接口中直接從請求頭中獲取token,從而實現驗證。
這里使用axios里的Interceptors方法,詳細可查閱axios手冊:

admin/http.js前端admin端將token傳入請求頭Request Header:
~~~
// 使用axios的interceptors攔截器,將http調用時攔截
http.interceptors.request.use(function(config){
// 將token值傳入請求頭,"bearer + 空格"是代碼規范,看到Bearer(持票人)大家就明白是對token的驗證
config.headers.Authorization = 'bearer ' + localStorage.token
return config
}, function(error){
// 錯誤處理
return Promise.reject(error)
})
~~~


隨便調用一個接口測試:
第二步,后端獲取請求頭中的token值,并解析token
因為所有接口的調用都需要驗證token,所以我們學習tp6的中間件,在每次接口調用時都使用此中間件進行token驗證。
middleware/compareToken.php:
~~~
<?php
namespace app\admin\middleware;
use \Firebase\JWT\JWT;
class compareToken{
public function handle ($request, \Closure $next){
// 獲取請求頭header中的authorization(token值)
$token = request() -> header('authorization');
// 去除token值中的bearer+空格標識
$token = str_replace('bearer ', '', $token);
// return response($token);
if($token === "undefined"){
// abort終止操作,返回結果
abort(json(['message' => '登陸狀態失效,請重新登錄', 'code' => 401], $httpCode = 401));
// return response($code);
}
// key必須與生成token值得字符串相同
$key='aslfjhasgjgja';
try {
JWT::$leeway = 60;//當前時間減去60,把時間留點余地用于后面的操作
$decoded = JWT::decode($token, $key, array('HS256')); //HS256方式,這里要和簽發的時候對應
// 解析過程中如果出現不對的情況就利用下方catch方法,利用jwt解析問題返回錯誤信息
} catch(\Firebase\JWT\SignatureInvalidException $e) { // token不正確
abort(json(['message' => '登陸狀態失效,請重新登錄', 'code' => 401], $httpCode = 401));
} catch(\Firebase\JWT\BeforeValidException $e) { // token過了之前設置的兩天期限
abort(json(['message' => '登陸狀態失效,請重新登錄', 'code' => 401], $httpCode = 401));
} catch(\Firebase\JWT\ExpiredException $e) { // token過期
abort(json(['message' => '登陸狀態失效,請重新登錄', 'code' => 401], $httpCode = 401));
} catch(Exception $e) { //其他錯誤
abort(json(['message' => '登陸狀態失效,請重新登錄', 'code' => 401], $httpCode = 401));
}
// 如果沒問題,就執行下一步接口函數操作
return $next($request);
}
}
~~~

admin/middleware.php:
~~~
<?php
// 這是系統自動生成的middleware定義文件
return [
// token驗證
app\admin\middleware\compareToken::class
];
~~~

測試,刷新頁面:

沒問題,是因為之前我們登錄時有token,下一步將localstorage中的token刪除:

再次刷新頁面測試:

到此token驗證成功。
但是還有一個問題,我們無法進行登錄,因為登錄接口同樣使用了token驗證中間件。
第三步,路由分組,使用路由中間件
(1)使用路由分組

(2)使用路由中間件
注釋掉全局路由:

使用路由中間件,作用于數據庫接口路由組:

登錄測試,成功登錄:

刪除localstorage,刷新測試,正確跳轉登錄:

但是經過多次測試后,發現會報錯,說是跨域問題:

但是經過一整天的排查,跟跨域一點關系都沒有。是請求request的問題。
說白了就是中間件next()之后request接受不到數據,于是我把return next()放在了函數首部:

至此之后不回出現跨域錯誤問題。
注意:他娘的tp6框架當你使用了框架內置的跨域之后就不要懷疑跨域會出問題,所有request請求相關問題他都會報錯說Cor error,大家不要在跨域上浪費時間!!!我白白浪費一天。
到此后端token驗證成功。
但是有些頁面沒有使用到后端接口,所以不會跳轉登陸頁面:

所以前端頁面我們需要用到vue的導航守衛。
###### 3.導航守衛
此時我們只要調用接口就會解析token,但是進入沒有接口的頁面就不會跳轉。如果我們不想讓用戶在不登陸的狀態下訪問我們的所有網頁,就需要在前端也設置token判斷,做到只要不登錄,就無法訪問所有頁面。
這里我們就需要用到Vue的導航守衛。
大家可以查看我之前的文章進行設置,純前端操作,不涉及后端:
> 技能學習:學習使用Node.js + Vue.js,開發前端全棧網站-12-4.登陸的前端vue-router路由驗證(導航守衛)
再注意:node.js + vue.js此篇文章使用的是sessionStorage,本篇文章我們使用的是localStorage,大家最終函數處應改為localStorage,否則無法登錄。

此時登錄功能全部完成,下篇文章我們做分類功能,同時學習通用CRUD接口,讓分類功能與管理員功能使用同一組接口函數。
- tp6+vue
- 1.工具和本地環境
- 2.啟動項目
- 3.路由、模型與數據庫操作
- 4.優化后端接口,前端使用axios實現接口功能
- 5.用戶登錄,bcrypt(hash)加密與驗證
- 6.用戶登錄(二),token驗證
- 7.分類的模型關聯和通用CRUD接口
- 8.使用vue的markdown編輯器并批量上傳圖片
- Node.js + Vue.js
- 工具,本地環境
- 2.1啟動項目
- 3.element-ui和vue-router路由的安裝和使用
- 4.使用axios,并創建接口上傳數據到mongodb數據庫
- 5.mongoodb數據庫的“刪、改、查”操作
- 6.mongodb數據庫無限層級的數據關聯(子分類)
- 7.使用mongodb數據庫關聯多個分類(關聯多個數據)
- 8.server端使用通用CRUD接口
- 9.圖片上傳
- 10.vue的富文本編輯器(vue2-editor)
- 11.動態添加分欄上傳多組數據
- 12-1.管理員模塊
- 13-1.搭建前臺web端頁面
- 1.使用sass工具搭建前臺web端頁面
- 2.sass工具的變量
- 3.使用flex布局并開始搭建web端
- 4.vue廣告輪播圖,并使用接口引入數據
- 5.使用字體圖標(iconfont)
- 6.卡片組件的封裝
- 14-1.生產環境編譯
- 1.環境編譯
- 2.購買域名服務器并解析域名到服務器
- 3.nginx配置web服務器并安裝網站環境
- 4.git拉取代碼到服務器
- 5.配置Nginx反向代理
- 6.遷移本地數據到服務器(mongodump)
- uni
- 1.工具&本地環境
- 2.頁面制作
- 3.頁面制作、組件與輪播
- 4.頁面跳轉與橫向滑動
- 5.用戶授權登錄和用戶信息獲取
- 6.用戶注冊和數據存儲
- 7.用戶填寫表單信息