上一篇文中,我们学习了什么是JWT(Json Web Token),今天我们来结合实例给大家讲述JWT的实战应用,就是如何使用前端Axios与后端PHP实现用户登录鉴权认证的过程。

文中涉及的重要知识点有:

因此在阅读这边文章之前,请先了解以上知识点以及JWT的基本概念,这样你会很快理解我们这篇文章中的实例代码。

准备

在本站上篇文章《有关JWT(Json Web Token)的那些事》有介绍用户登录鉴权流程:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

那么现在我们就按这个流程开始。

HTML

我们的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>

详细的代码,可以下载demo源码中查看,这里样式我们使用的是Bootstrap3的经典样式。

Javascript

前端Javascript异步请求,我们使用Axios库,当然你也可以使用jQuery的Ajax方法。

首先引入axios库:

<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里,再次去请求后端另一个用户信息接口,如果成功了就显示用户信息。

如果要退出登录,我们不需要再次去请求后端接口,直接前端清空本地存储就OK了。

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';
}

  

PHP

后端我们使用了一个专门的JWT库:php-jwt

使用composer安装php-jwt,接收到登录用户名和密码后,PHP验证用户名和密码是否正确(实际开发中应该结合数据库,从数据库里拿用户名和密码比对,本实例为了演示只做简单验证),如果用户名和密码准确无误,那么就签发token,在token中,我们可以定义token的签发者、过期时间等等,并返回给前端。注意在签发token时,我们需要定义一个密钥,这个密钥是一个私钥,实际应用中是保密的不可告诉别人。

require '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头信息中。

然后PHP拿到这个token后,解密分析token值,返回给前端即可。

结束语

以上就是整个JWT的实战应用,我们可以看到,在用户鉴权的过程中并没有使用Session或者Cookie,服务端无需存储用户会话信息。只用了一个Token串,建立前后端的验证的数据传递,实现了有效的登录鉴权过程。

JWT实战:使用axios+PHP实现登录认证的更多相关文章

  1. 实战模拟│JWT 登录认证

    目录 Token 认证流程 Token 认证优点 JWT 结构 JWT 基本使用 实战:使用 JWT 登录认证 Token 认证流程 作为目前最流行的跨域认证解决方案,JWT(JSON Web Tok ...

  2. 基于jwt的用户登录认证

    最近在app的开发过程中,做了一个基于token的用户登录认证,使用vue+node+mongoDB进行的开发,前来总结一下. token认证流程: 1:用户输入用户名和密码,进行登录操作,发送登录信 ...

  3. Luffy之登录认证以及JWT

    1.用户认证 在前面我们已经完成了,前端登录页面的搭建,以及路由分配,现在我们作关于登录认证部分的东西 Django提供了认证系统.认证系统包含: 用户 权限:二元(是/否)标志指示一个用户是否可以做 ...

  4. springboot+jwt完成登录认证

    本demo用于测试jwt,通过登录验证通过后,使用jwt生成token,然后在请求header中携带token完成访问用户列表信息. 准备工作: 1. 实体类SysUser.java package ...

  5. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_4-3.登录检验JWT实战之封装通用方法

    笔记 3.登录检验JWT实战之封装通用方法     讲解:引入相关依赖并开发JWT工具类 1.加入相关依赖 <!-- JWT相关 -->             <dependenc ...

  6. 基于JWT的Token登录认证(一)

    1.JWT简介 JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案. session登录认证方案:用户从客户端传递用户名.密码等信息,服务端认证后将信息存储在session中 ...

  7. 【项目实践】一文带你搞定Session和JWT的登录认证方式

    以项目驱动学习,以实践检验真知 前言 登录认证,估计是所有系统中最常见的功能了,并且也是最基础.最重要的功能.为了做好这一块而诞生了许多安全框架,比如最常见的Shiro.Spring Security ...

  8. 厉害!我带的实习生仅用四步就整合好SpringSecurity+JWT实现登录认证!

    小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么锅都想甩给他,啊,不,一不小心怎么把心里话全说出来了呢?重来! 小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么 ...

  9. SpringBoot整合JWT实现登录认证

    什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...

随机推荐

  1. 1.3 fractions模块

    数学世界中,浮点数还可以用分数形式展示,不可约简的分数形式往往更简洁直观.  问题来了,Python中如何输出不可约简的分数形式呢?  答案:用Fraction类来实现.这个类属于标准库的fracti ...

  2. nyoj222 整数中的1 数位DP

    从a枚举到b是一定会超时的.此题应该考虑数位dp,也可以理解为递推,假设给定数n,就能在O(32)复杂度算出所有小于等于n的数中1出现的次数,那么给定区间[a, b],solve(b) - solve ...

  3. LOJ116 - 有源汇有上下界最大流

    原题链接 Description 模板题啦~ Code //有源汇有上下界最大流 #include <cstdio> #include <cstring> #include & ...

  4. string (KMP+期望DP)

    Time Limit: 1000 ms   Memory Limit: 256 MB Description  给定一个由且仅由字符 'H' , 'T' 构成的字符串$S$. 给定一个最初为空的字符串 ...

  5. MyEclipse中如何去掉JS/JSP语法错误提示

    一    优化一下MyEclipse 1 .关闭MyEclipse的自动validation      windows > perferences > myeclipse > val ...

  6. Linux基础二

    linux命令分类 内部命令:属于shell解释器 外部命令:独立于shell解释器 检查命令类型 type:检查命令字的类型 [root@localhost ~]# type ls ls 是 `ls ...

  7. Davinci DM6446 Codec Engine双核通信环境的搭建

    根据前几篇文章,一个DM6446的系统已经架构完成.但是有很多人都喜欢TI的机制,毕竟双核软件开发对很多工程师来说是非常麻烦的事情,既然TI提供开发套件和开发包,那么直接做OEM就可以了,底层的东西不 ...

  8. 关于druid的配置说明

    <bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter"> & ...

  9. 【html5】html5离线存储

    html5本地存储之离线存储 1.为什么使用离线存储 ①最新的主流的浏览器中都已添加了对HTML5的offline storage功能的支持,HTML5离线存储功能非常强大, 它的作用是:在用户没有与 ...

  10. 【mongodb系统学习之八】mongodb shell常用操作

    八.mongodb  shell常用基础操作(每个语句后可以加分号,也可以不加,看情况定(有的工具中可以不加),最好是加): 1).进入shell操作界面:mongo,上边已有演示: 2).查看当前使 ...