网站首页 > 基础教程 正文
首先了解一下什么是JWT?JWT是一个简单的PHP的第三方库,用于在PHP中编码和解码JSON WEB令牌jwt 。一般用composer来管理依赖关系 使用composer require firebase/php-jwt来安装这个库(详见 php-jwt库:https://github.com/firebase/php-jwt)
再来介绍一下用户登录鉴权流程
1、用户使用用户名和密码来请求服务器
2、服务器验证用户信息
3、服务器通过验证生成一个token返回给客户端
4、客户端存储这个token,并在后面的每一次请求中在请求头上带上这个token
5、服务端验证这个token token正确就返回数据 token错误就返回错误信息
start 首先我们需要一个html表单用于后台的登录
<div id="showpage" style="display: none">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" class="form-control" id="username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" class="form-control" id="password" placeholder="请输入密码">
</div>
<button type="submit" id="sub-btn" class="btn btn-default">登录</button> <br/>
<p class="bg-warning" style="padding: 10px;">演示用户名和密码都是<code>demo</code></p>
</div>
<div id="user" style="display: none">
<p>欢迎<strong id="uname">
</strong>,您已登录,<a href="javascript:;" id="logout">退出>></a>
</p>
</div>
// 使用axios库
<script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
<script>
let jwt = localStorage.getItem('jwt');
// token 保存在localstorage里面 判断有没有token
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';
}
document.querySelector("#sub-btn").onclick = function(){
let username = document.querySelector("#username").value;
let password = document.querySelector("#password").value;
var params = new URLSearchParams();
params.append('user',username);
params.append('pass',password);
axios.post(
'user.php?action=login',
params,
);
.then(response) => {
if(response.data.result === 'success'){
// 本地存储token
localStorage.setItem('jwt',response.data.jwt);
// 把token存储到header里面
axios.defaults.headers.common['X-token'] = response.data.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{
}
})
}else{
console.log(response.data.msg);
}
}
.catch(function(error){
console.log(error);
});
}
</script>
服务器端
首先使用php-jwt库
使用composer安装php-jwt,接收到登录用户名和密码后,PHP验证用户名和密码是否正确,如果用户名和密码准确无误,那么就签发token,在token中,我们可以定义token的签发者、过期时间等等,并返回给前端。注意在签发token时,我们需要定义一个密钥,这个密钥是一个私钥,实际应用中是保密的不可告诉别人。
后台代码user.php
<?php
date_default_timezone_set("PRC"); //系统使用北京时间
require 'vendor/autoload.php';
use \Firebase\JWT\JWT;
// 私有的密钥
define('KEY', '1gHuiop975cdashyex9Ud23ldsvm2Xq');
// header('Access-Control-Allow-Origin:*');
$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') { //用户名和密码正确,则签发tokon
$nowtime = time();
$token = [
'iss' => 'http://www.helloweba.net', //签发者
'aud' => 'http://www.helloweba.net', //jwt所面向的用户
'iat' => $nowtime, //签发时间
'nbf' => $nowtime + 10, //在什么时间之后该jwt才可用
'exp' => $nowtime + 600, //过期时间-10min
'data' => [
'userid' => 1,
'username' => $username
]
];
// 生成token
$jwt = JWT::encode($token, KEY);
$res['result'] = 'success';
$res['jwt'] = $jwt;
} else {
$res['msg'] = '用户名或密码错误!';
}
}
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'] = '请重新登录';
} else {
$res['result'] = 'success';
$res['info'] = $arr;
}
} catch(Exception $e) {
$res['msg'] = 'Token验证失败,请重新登录';
}
echo json_encode($res);
}
用户每次请求都要带上后端签发的token,后端获取请求中的token,PHP中使用$_SERVER['HTTP_X_TOKEN']就可以获取token值。这个X_TOKEN就是在我们前端的请求header头信息中。
然后PHP拿到这个token后,解密分析token值,返回给前端即可。
我们可以看到,在用户鉴权的过程中并没有使用Session或者Cookie,服务端无需存储用户会话信息。只用了一个Token串,建立前后端的验证的数据传递,实现了有效的登录鉴权过程。
猜你喜欢
- 2025-01-18 面向开发人员的 Kubernetes: 9 有状态应用程序 (1) 卷、持久卷和存储
- 2025-01-18 php 发送微信订阅消息
- 2025-01-18 weiphp图灵机器人存在的bug
- 2025-01-18 X语言解析器C++实现(模糊探索篇)
- 2025-01-18 100 个常见的 PHP 面试题和答案分享
- 2025-01-18 PHP 运算符和表达式
- 2025-01-18 php提示undefined index的几种解决方法
- 2025-01-18 通过冒泡排序测试Java和PHP性能
- 2025-01-18 PHP使用Phar打包控制台程序
- 2025-01-18 PHP8内置函数中的变量函数-PHP8知识详解
- 05-162025前端最新面试题之HTML和CSS篇
- 05-16大数据开发基础之HTML基础知识
- 05-16微软专家告诉你Win10 Edge浏览器和EdgeHTML的区别
- 05-16快速免费将网站部署到公网方法(仅支持HTML,CSS,JS)
- 05-16《从零开始学前端:HTML+CSS+JavaScript的黄金三角》
- 05-16一个简单的标准 HTML 设计参考
- 05-16css入门
- 05-16前端-干货分享:更牛逼的CSS管理方法-层(CSS Layers)
- 最近发表
- 标签列表
-
- jsp (69)
- pythonlist (60)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- deletesql (62)
- c++模板 (62)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- console.table (62)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)