<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>详细的代码,可以下载demo源码中查看,这里样式我们使用的是Bootstrap3的经典样式。<script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>按照流程,1.提交登录表单,发送用户名和密码到PHP后端,2.后端验证成功后,会发送一个token给前端,3.前端再拿这个token去请求需要用户权限访问,4.后端验证toen,鉴权,返回相应结果。下面的js代码实现了1,3两步。<script>
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>很显然,当登录成功后,立马使用本地存储token,然后把这个token放在请求头header里,再次去请求后端另一个用户信息接口,如果成功了就显示用户信息。document.querySelector('#logout').onclick = function() {
localStorage.removeItem('jwt');
document.querySelector('#showpage').style.display = 'block';
document.querySelector('#user').style.display = 'none';
}登录成功后,当我们刷新页面(再次请求需要登录后才能访问的页面),需要进行判断,判断本地存储中是否有token,如果有token,那就拿去给后端接口验证下token是否合法,如果没问题就显示用户相关信息,如果验证失败,那可能是token过去或者伪造的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';
}PHPrequire 'vendor/autoload.php';
use \Firebase\JWT\JWT;
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') { //用户名和密码正确,则签发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
]
];
$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头信息中。ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。