文档章节

聊一聊数据接口的登录态校验以及JWT

祺爸PiscDong
 祺爸PiscDong
发布于 12/02 23:40
字数 1597
阅读 1104
收藏 15
JWt

最近和群里网友聊天,发现他在数据接口中校验登录状态用的还是session,在我及时劝说和科普之后,他最终决定改用JWT。那么接下来我们就聊一聊数据接口应该怎么管理登录状态以及什么是JWT

混合开发的时候是怎么做的

前后端混合开发的时候,用户登录状态的管理一般都是通过session来实现的,原理很简单:用户登录后,服务端将登录用户信息存储到服务器上的特定位置,并生成对应的session id存储到浏览器的cookie中。需要校验的时候先读取cookie中的session id,找到服务器中对应的存储内容,完成校验。

很显然,这个机制是建立在cookie基础上的,cookie又依赖于浏览器,而且有域名限制。是不适合app、小程序、以及前后端时数据接口采用其他域名等情况的。

app、小程序、前后端分离的时候要怎么做

app、小程序、前后端分离时的数据接口一般采用token来做登录信息校验。原理是用户登录后,服务端生成对应用户的一个token(一般都是一段无意义的唯一字符串)后返回,app、小程序、前端(以下统称为前端)拿到token后保存,在需要校验用户登录的接口请求中加入token(可以是get、post参数或者http header的形式),服务端拿到token后校验真实性、有效性等信息后完成登录校验。一般为了防止盗用,还会设置一套签名校验的过程。

其实token和session的原理是差不多的,都是服务端将对应用户的一个key(session的时候是session id,token的时候就是token)交给前端,前端通过token请求服务端,服务端再去反查用户,获取用户登录状态。

现在一般微信、微博等接口都是采用的这种方式。但是这种方式也有弊端,主要是:

  1. 服务端必须保存token,以及有效期,校验的时候必须要有数据读取的过程;
  2. 校验签名的时候一般需要一个secret做为加密签名的附加字符,前端必须也要同时保存这个secret,这样显然不适合代码会暴露的网页前端。

这时候,就轮到我们这次的主角JWT出场了。

什么是JWT

JWT是JSON Web Token的简称,有官网详细介绍,大家可以看一看,这里简单说一下。

JWT其实就是一种特殊的token,原理和使用方法自然和token一样。

JWT是由三部分组成的字符串,结构是:头部+主体内容(官方称之为Payload)+签名,三部分用“.”连接。头部和主体内容都是json格式的字符串再经过base64编码,为了方便放在get请求中,还需要把类似“=”、“/”等特殊字符替换掉。

头部内容是固定的,原始json就是下面这样

{
	"alg": "HS256",
	"typ": "JWT"
}

主要是说明了最后签名部分的加密算法。

重点是中间的主体内容,原始json一般是类似下面这样的

{
	"user": "John Doe",
	"exp": "2020-01-01 12:24:30"
}

主体内容一个是当前登录的用户,可以是用户id,也可以是用户名等可以检索定位到用户的信息;还有一个就是过期时间。还可以加入一些其他不私密的信息。

服务端拿到JWT之后可以在不读取数据的情况下,仅通过解码这部分信息就可以完成获取登录用户以及判断是否过期等初期工作。

最后的签名一般是把头部、主体内容再加上secret拼接成字符串再加密,这一步在用户登录生成JWT的时候就完成了。服务端拿到JWT之后只需要把前两部分加上secret再计算一次签名加以比对就可以完成校验签名,前端不需要同时保存secret。

JWT官网提供了各种服务端语言的生成代码,这里我提供一个我自己用PHP写的相对简化的方法,供大家参考

private function _jwt($payload){
	$header['alg']='HS256';
	$header['typ']='JWT';
	$jwt_header=$this->_base64url($header);
	$jwt_payload=$this->_base64url($payload);
	$jwt_sign=hash_hmac('sha256', $jwt_header.'.'.$jwt_payload, $this->secret);
	$jwt['token']=$jwt_header.'.'.$jwt_payload.'.'.$jwt_sign;
	$jwt['sign']=$jwt_sign;
	return $jwt;
}

private function _base64url($a){
	$c=base64_encode(json_encode($a));
	$c=str_replace('=', '', $c);
	$c=str_replace('+', '-', $c);
	$c=str_replace('/', '_', $c);
	return $c;
}

我这个方法里需要把主题内容以数组形式的参数传入,最终返回了生成的JWT和签名,方便接收时校验签名。

最后再说一下缺点

JWT在实际使用中也是存在问题的,目前想到以下几点:

  1. 安全性:签名包含在token中,一旦token整体被盗用,将没有办法区分,所以有网友称之为“裸奔”;
  2. 过期时间放在token中而不是服务端保存处理,一旦token生成并签发出去,将无法灵活的控制有效期;
  3. 最后一个是用户体验,其实可以算是token方式的通病。这个问题我也和群友讨论过,大家在访问部分社区的时候应该会遇到过,还在访问过程中突然变成未登录。我觉得这主要时因为服务端在token过期后就即时判断为用户登录失败,不管你在网页上处于什么状态。这个问题在session方式中是不存在的,前面说过session依赖于cookie,而存储session id的cookie是会保存在整个浏览器进程,就是说只要浏览器不关闭,用户就可以一直保持登录状态。

© 著作权归作者所有

祺爸PiscDong

祺爸PiscDong

粉丝 32
博文 5
码字总数 5020
作品 0
浦东
程序员
私信 提问
加载中

评论(10)

假老练
假老练
jwt 像HTTP无状态一样,只需要验证 载荷解析处理而不需要存储,也有的文章说不建议使用jwt说安全性不可靠,毕竟通过bash64可以解析出来,但是我个人觉得jwt还是一个实用性非常高的技术
衷于栖
衷于栖
你说的缺点一个refresh token都解决了
祺爸PiscDong
祺爸PiscDong 博主
服务端调接口的时候,可以用refresh token,但是小程序、网页等前端就不适合了 还有不知道你这个“都”是指哪几个缺点,我列出的全部?不行吧
衷于栖
衷于栖
安全性,只要是web应用就有这个问题,说的是后边两个
祺爸PiscDong
祺爸PiscDong 博主
麻烦分享一下解决方案,谢谢
Joyzhou
Joyzhou
是的,refresh token都可以解决
祺爸PiscDong
祺爸PiscDong 博主
麻烦分享一下解决方案,谢谢
漠孤烟
漠孤烟
refresh token,就是续签吧。 session是自动续签,永远以最后一次访问的时间做为起始计时时间,refresh token则是间断续签。 session能剔账户下线,jwt无法。 各有优劣吧。
衷于栖
衷于栖
一般token有效期短 refresh有效期长 这样就能踢了 只不过有个延迟,需要特殊处理的 应该会在程序里直接屏蔽账户,
祺爸PiscDong
祺爸PiscDong 博主
有效期长短和能不能踢好像没有关系啊
理解JSON Web Token【译】

原文 本文我们将来聊一聊JSON Web Token是什么。 先介绍一下他的基本概念,再来看看它的结构、最后创建一个服务器来获取一些数据然后插入到一个JWT中。 什么是JSON Web Token?为什么我们需要...

ITgecko
2018/11/27
0
0
jwt 实践应用以及特殊案例思考

JSON Web Token 是 rfc7519 出的一份标准,使用 JSON 来传递数据,用于判定用户是否登录状态。 jwt 之前,使用 来做用户认证。 以下代码均使用 javascript 编写。 原文链接: 山月的博客 sess...

shanyue
11/21
0
0
JWT refreshtoken 实践

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

goodspeed
04/29
0
0
除了cookie,你还可以用jwt(json web token)!

1. 认识jwt(json web token) jwt是为了在网络应用环境传递声明而执行的一种基于json的开放标准。 jwt被用来在身份提供者和服务提供者间传递被认证的用户身份信息,简单来说,就是用来验证身...

Jeffywin
2018/08/03
0
0
Java中使用JWT生成Token进行接口鉴权实现

先介绍下利用JWT进行鉴权的思路: 1、用户发起登录请求。 2、服务端创建一个加密后的JWT信息,作为Token返回。 3、在后续请求中JWT信息作为请求头,发给服务端。 4、服务端拿到JWT之后进行解...

小怪聊职场
2018/12/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud简介,微服务架构,以及与Dubbo的详细比较

什么是Spring Cloud Spring Cloud 是一套完整的微服务解决方案,基于 Spring Boot 框架,准确的说,它不是一个框架,而是一个大的容器,它将市面上较好的微服务框架集成进来,从而简化了开发...

一只会编程的狼
刚刚
0
0
检查Ruby中的数组中是否存在值

我有一个值'Dog'和一个阵列['Cat', 'Dog', 'Bird'] 。 如何在没有循环的情况下检查数组中是否存在? 是否有一种简单的方法来检查值是否存在,仅此而已? #1楼 有一个in? 方法中ActiveSupport......

技术盛宴
1分钟前
0
0
技术分享 | 使用 Perf 和火焰图分析软件

作者:Agustín 翻译:孟维克 原文:https://www.percona.com/blog/2019/11/20/profiling-software-using-perf-and-flame-graphs/ 在这篇博文中,我们将探讨如何一起使用perf和火焰图。它们用...

爱可生
2分钟前
0
0
什么是区块链和节点?

首先你要知道,节点(node)只是一个词,在网络相关的文献里很常见,在不同的语境,不同的系统里会有不同的意思,并不是所有的区块链乃至p2p网络里提到节点都指的一个东西。 其次,区块链这东...

专注的阿熊
5分钟前
0
0
解决传导干扰八大绝招

引言 电磁干扰EMI中电子设备产生的干扰信号是通过导线或公共电源线进行传输,互相产生干扰称为传导干扰。传导干扰给不少电子工程师带来困惑,如何解决传导干扰?找对方法,你会发现,传导干扰...

demyar
6分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部