摘要:今天我們來(lái)結(jié)合實(shí)例給大家講述的實(shí)戰(zhàn)應(yīng)用,就是如何使用前端與后端實(shí)現(xiàn)用戶登錄鑒權(quán)認(rèn)證的過(guò)程。只用了一個(gè)串,建立前后端的驗(yàn)證的數(shù)據(jù)傳遞,實(shí)現(xiàn)了有效的登錄鑒權(quán)過(guò)程。
今天我們來(lái)結(jié)合實(shí)例給大家講述JWT(Json Web Token)的實(shí)戰(zhàn)應(yīng)用,就是如何使用前端Axios與后端PHP實(shí)現(xiàn)用戶登錄鑒權(quán)認(rèn)證的過(guò)程。
文中涉及的重要知識(shí)點(diǎn):axios異步請(qǐng)求:axios-基于Promise的HTTP請(qǐng)求客戶端
php-jwt庫(kù):https://github.com/firebase/p...
HTML5相關(guān)知識(shí)
因此在閱讀這邊文章之前,請(qǐng)先了解以上知識(shí)點(diǎn)以及JWT的基本概念,這樣你會(huì)很快理解我們這篇文章中的實(shí)例代碼。
用戶登錄鑒權(quán)流程:
用戶使用用戶名密碼來(lái)請(qǐng)求服務(wù)器
服務(wù)器進(jìn)行驗(yàn)證用戶的信息
服務(wù)器通過(guò)驗(yàn)證發(fā)送給用戶一個(gè)token
客戶端存儲(chǔ)token,并在每次請(qǐng)求時(shí)附送上這個(gè)token值
服務(wù)端驗(yàn)證token值,并返回?cái)?shù)據(jù)
那么現(xiàn)在我們就按這個(gè)流程開(kāi)始。
我們的HTML結(jié)構(gòu)是這樣的:一個(gè)登錄表單,供用戶輸入用戶名和密碼,以及提交按鈕;一個(gè)是登錄成功后的顯示信息。
詳細(xì)的代碼,可以下載demo源碼中查看,這里樣式我們使用的是Bootstrap3的經(jīng)典樣式。
Javascript前端Javascript異步請(qǐng)求,我們使用Axios庫(kù),當(dāng)然你也可以使用jQuery的Ajax方法。
首先引入axios庫(kù):
按照流程,
1.提交登錄表單,發(fā)送用戶名和密碼到PHP后端,
2.后端驗(yàn)證成功后,會(huì)發(fā)送一個(gè)token給前端,
3.前端再拿這個(gè)token去請(qǐng)求需要用戶權(quán)限訪問(wèn),
4.后端驗(yàn)證toen,鑒權(quán),返回相應(yīng)結(jié)果。
下面的js代碼實(shí)現(xiàn)了1,3兩步。
很顯然,當(dāng)?shù)卿洺晒?,立馬使用本地存儲(chǔ)token,然后把這個(gè)token放在請(qǐng)求頭header里,再次去請(qǐng)求后端另一個(gè)用戶信息接口,如果成功了就顯示用戶信息。
如果要退出登錄,我們不需要再次去請(qǐng)求后端接口,直接前端清空本地存儲(chǔ)就OK了。
document.querySelector("#logout").onclick = function() { localStorage.removeItem("jwt"); document.querySelector("#showpage").style.display = "block"; document.querySelector("#user").style.display = "none"; }
登錄成功后,當(dāng)我們刷新頁(yè)面(再次請(qǐng)求需要登錄后才能訪問(wèn)的頁(yè)面),需要進(jìn)行判斷,判斷本地存儲(chǔ)中是否有token,如果有token,那就拿去給后端接口驗(yàn)證下token是否合法,如果沒(méi)問(wèn)題就顯示用戶相關(guān)信息,如果驗(yàn)證失敗,那可能是token過(guò)去或者偽造的token等原因。
let jwt = localStorage.getItem("jwt"); if (jwt) { axios.defaults.headers.common["X-token"] = jwt; axios.get("user.php") .then(function (response) { if (response.data.result === "success") { document.querySelector("#showpage").style.display = "none"; document.querySelector("#user").style.display = "block"; document.querySelector("#uname").innerHTML = response.data.info.data.username; } else { document.querySelector("#showpage").style.display = "block"; console.log(response.data.msg); } }) .catch(function (error) { console.log(error); }); } else { document.querySelector("#showpage").style.display = "block"; }PHP
后端我們使用了一個(gè)專門的JWT庫(kù):php-jwt
使用composer安裝php-jwt,接收到登錄用戶名和密碼后,PHP驗(yàn)證用戶名和密碼是否正確(實(shí)際開(kāi)發(fā)中應(yīng)該結(jié)合數(shù)據(jù)庫(kù),從數(shù)據(jù)庫(kù)里拿用戶名和密碼比對(duì),本實(shí)例為了演示只做簡(jiǎn)單驗(yàn)證),如果用戶名和密碼準(zhǔn)確無(wú)誤,那么就簽發(fā)token,在token中,我們可以定義token的簽發(fā)者、過(guò)期時(shí)間等等,并返回給前端。注意在簽發(fā)token時(shí),我們需要定義一個(gè)密鑰,這個(gè)密鑰是一個(gè)私鑰,實(shí)際應(yīng)用中是保密的不可告訴別人。
require "vendor/autoload.php"; use FirebaseJWTJWT; define("KEY", "1gHuiop975cdashyex9Ud23ldsvm2Xq"); //密鑰 $res["result"] = "failed"; $action = isset($_GET["action"]) ? $_GET["action"] : ""; if ($action == "login") { if ($_SERVER["REQUEST_METHOD"] == "POST") { $username = htmlentities($_POST["user"]); $password = htmlentities($_POST["pass"]); if ($username == "demo" && $password == "demo") { //用戶名和密碼正確,則簽發(fā)tokon $nowtime = time(); $token = [ "iss" => "http://www.helloweba.net", //簽發(fā)者 "aud" => "http://www.helloweba.net", //jwt所面向的用戶 "iat" => $nowtime, //簽發(fā)時(shí)間 "nbf" => $nowtime + 10, //在什么時(shí)間之后該jwt才可用 "exp" => $nowtime + 600, //過(guò)期時(shí)間-10min "data" => [ "userid" => 1, "username" => $username ] ]; $jwt = JWT::encode($token, KEY); $res["result"] = "success"; $res["jwt"] = $jwt; } else { $res["msg"] = "用戶名或密碼錯(cuò)誤!"; } } echo json_encode($res); } else { $jwt = isset($_SERVER["HTTP_X_TOKEN"]) ? $_SERVER["HTTP_X_TOKEN"] : ""; if (empty($jwt)) { $res["msg"] = "You do not have permission to access."; echo json_encode($res); exit; } try { JWT::$leeway = 60; $decoded = JWT::decode($jwt, KEY, ["HS256"]); $arr = (array)$decoded; if ($arr["exp"] < time()) { $res["msg"] = "請(qǐng)重新登錄"; } else { $res["result"] = "success"; $res["info"] = $arr; } } catch(Exception $e) { $res["msg"] = "Token驗(yàn)證失敗,請(qǐng)重新登錄"; } echo json_encode($res); }
用戶每次請(qǐng)求都要帶上后端簽發(fā)的token,后端獲取請(qǐng)求中的token,PHP中使用$_SERVER["HTTP_X_TOKEN"]就可以獲取token值。這個(gè)X_TOKEN就是在我們前端的請(qǐng)求header頭信息中。
然后PHP拿到這個(gè)token后,解密分析token值,返回給前端即可。
結(jié)束語(yǔ)以上就是整個(gè)JWT的實(shí)戰(zhàn)應(yīng)用,我們可以看到,在用戶鑒權(quán)的過(guò)程中并沒(méi)有使用Session或者Cookie,服務(wù)端無(wú)需存儲(chǔ)用戶會(huì)話信息。只用了一個(gè)Token串,建立前后端的驗(yàn)證的數(shù)據(jù)傳遞,實(shí)現(xiàn)了有效的登錄鑒權(quán)過(guò)程。
在線演示demo:https://www.helloweba.net/dem...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28419.html
摘要:認(rèn)證服務(wù)器,即服務(wù)提供商專門用來(lái)處理認(rèn)證的服務(wù)器。它與認(rèn)證服務(wù)器,可以是同一臺(tái)服務(wù)器,也可以是不同的服務(wù)器??蛻舳耸褂蒙弦徊将@得的授權(quán),向認(rèn)證服務(wù)器申請(qǐng)令牌。認(rèn)證服務(wù)器對(duì)客戶端進(jìn)行認(rèn)證以后,確認(rèn)無(wú)誤,同意發(fā)放令牌。 最近想做個(gè)小程序,需要用到授權(quán)認(rèn)證流程。以前項(xiàng)目都是用的 OAuth2 認(rèn)證,但是Sanic 使用OAuth2 不太方便,就想試一下 JWT 的認(rèn)證方式。這一篇主要內(nèi)容是 ...
摘要:部分是對(duì)前兩部分的簽名,防止數(shù)據(jù)篡改。也就是說(shuō),一旦簽發(fā)了,在到期之前就會(huì)始終有效,除非服務(wù)器部署額外的邏輯。為了減少盜用,的有效期應(yīng)該設(shè)置得比較短。為了減少盜用,不應(yīng)該使用協(xié)議明碼傳輸,要使用協(xié)議傳輸。 JSON Web Token(縮寫 JWT)是目前最流行的跨域認(rèn)證解決方案,本文介紹它的原理和用法。 showImg(https://www.wangbase.com/blogimg...
摘要:登錄認(rèn)證幾乎是任何一個(gè)系統(tǒng)的標(biāo)配,系統(tǒng)客戶端等,好多都需要注冊(cè)登錄授權(quán)認(rèn)證。假設(shè)我們開(kāi)發(fā)了一個(gè)電商平臺(tái),并集成了微信登錄,以這個(gè)場(chǎng)景為例,說(shuō)一下的工作原理。微信網(wǎng)頁(yè)授權(quán)是授權(quán)碼模式的授權(quán)模式。 登錄認(rèn)證幾乎是任何一個(gè)系統(tǒng)的標(biāo)配,web 系統(tǒng)、APP、PC 客戶端等,好多都需要注冊(cè)、登錄、授權(quán)認(rèn)證。 場(chǎng)景說(shuō)明 以一個(gè)電商系統(tǒng),假設(shè)淘寶為例,如果我們想要下單,首先需要注冊(cè)一個(gè)賬號(hào)。擁有了賬...
摘要:自己在前后端分離上的實(shí)踐要想實(shí)現(xiàn)完整的前后端分離,安全這塊是繞不開(kāi)的,這個(gè)系統(tǒng)主要功能就是動(dòng)態(tài)管理,這次實(shí)踐包含兩個(gè)模塊基于搭建的權(quán)限管理系統(tǒng)后臺(tái)編寫的前端管理。 自己在前后端分離上的實(shí)踐 要想實(shí)現(xiàn)完整的前后端分離,安全這塊是繞不開(kāi)的,這個(gè)系統(tǒng)主要功能就是動(dòng)態(tài)restful api管理,這次實(shí)踐包含兩個(gè)模塊,基于springBoot + shiro搭建的權(quán)限管理系統(tǒng)后臺(tái)bootshir...
摘要:自己在前后端分離上的實(shí)踐要想實(shí)現(xiàn)完整的前后端分離,安全這塊是繞不開(kāi)的,這個(gè)系統(tǒng)主要功能就是動(dòng)態(tài)管理,這次實(shí)踐包含兩個(gè)模塊基于搭建的權(quán)限管理系統(tǒng)后臺(tái)編寫的前端管理。 自己在前后端分離上的實(shí)踐 要想實(shí)現(xiàn)完整的前后端分離,安全這塊是繞不開(kāi)的,這個(gè)系統(tǒng)主要功能就是動(dòng)態(tài)restful api管理,這次實(shí)踐包含兩個(gè)模塊,基于springBoot + shiro搭建的權(quán)限管理系統(tǒng)后臺(tái)bootshir...
閱讀 1719·2023-04-26 02:30
閱讀 1049·2021-11-10 11:36
閱讀 1396·2021-10-08 10:14
閱讀 3522·2021-09-28 09:35
閱讀 1561·2021-08-23 09:47
閱讀 2561·2019-08-30 15:56
閱讀 1482·2019-08-30 15:44
閱讀 1774·2019-08-30 13:59