你在用 JWT 代替 Session?
现在,JSON Web Tokens (JWT) 是非常流行的。尤其是 Web 开发领域。
- 流行
- 安全
- 稳定
- 易用
- 支持 JSON
所有这些因素,令 JWT 名声大振。
但是,今天我要来说说使用 JWT 的缺点。也就是为什么说将 JWT 用于会话控制是多么的糟糕。
为什么使用 JWT?
如果你不了解 JWT,不要紧张,它并不可怕。
JWT 只是用于网络间传递声明而执行一种基于 JSON 的标准。
例如,我是个盲人,而且听力也不好。你上周帮我买了午餐,现在我需要你的收款账号,把钱还给你。如果我询问你的账号,但是其他人高呼他们的账号,由于我把别人的账号误认为是你的,我可能会不小心把钱打给别人。
JWT 旨在防止这种情况发生。JWT 提供了一种简单的方法,在彼此传递数据时,验证是由谁先创建了数据。
所以,像上述的例子,即使我收到了超过 100 万个 JWT 返回的账号信息,我也很容易可以辨别出来哪个真实来自于你。
JWT 如何运行?
JWT 是 JSON 格式的被加密了的字符串。
JWT 的核心是密钥,就是 JSON 数据。这是你关心的,并希望安全传递出去的数据。JWT 如何做到这一点,并使你信任它,就是加密签名。
比如说,我写了一封信,当我署名这封信时,意味着只要读过这封信的人,都知道是我写了这封信。而且我的签名是独一无二的,所以不会被怀疑真实性。加密签名的方式大致相同,JWT 有两种加密方式:对称加密和非对称加密,两种方式有同等的效用。
JWT 内容加密
其实,JWT 的内容(内部的 JSON 数据)通常是不加密的。这意味着,即使没有密钥,也可以查看 JWT 内的数据。JWT 默认并不会加密你的数据,它只是帮助你验证是你信任的一方创建了它。
如果你确实需要加密 JWT 内容,可以使用 JWE 进行加密,但这种做法并不常见。请确保使用了正确的方法。
如今人们是如何使用 JWT 的?
JWT 最常见的用途是身份验证。有大量的 Web 安全库使用 JWT 创建会话控制,API 令牌等。
这种做法通常是,当需要对网站/ API 进行身份验证时,服务器生成一个包含用户 ID 的 JWT,以及其它一些关键性的信息,然后再将其发送给浏览器/客户端等,存储为会话令牌。
例如,当用户访问网站上的另一个页面时,浏览器会自动将该 JWT 发送到服务器,服务器验证 JWT 确认和最初创建的令牌相同,然后允许用户执行后续的操作。
从理论上看,还不错,因为:
- 当服务器收到 JWT 时,可以验证其是否是合法的,是否是信任用户的令牌
- 可以在服务器本地验证,而不需要任何其它的网络请求,与数据库的通信等。这可能令管理会话更高效,因为无需从数据库(缓存)加载用户信息,只需要在本地运行一小部分代码。这可能是人们喜欢用 JWT 的最大原因。
似乎很棒,既可以提高 Web 应用的性能,又可以减少缓存服务器和数据库服务器的负载,提供更好的体验。另外你还可以在 JWT 中存储用户权限信息、用户个人信息等等更多的额外信息进一步减少数据库压力。
为什么 JWT 不是最好的会话令牌?
我们已经了解了 JWT 如何用于身份验证,让我们进入本篇的中心话题:为什么 JWT 不是最好的会话令牌,为什么普通的旧会话方式在几乎各方面都优于 JWT。
背景
我们先了解一些背景知识。开发人员构建的大多数网站都相对比较简单:
- 用户注册
- 用户登录
- 用户点击执行操作
- 网站使用用户信息进行创建、删除、更新、查阅信息
对于这类网站,要知道用户进行交互的每个页面都会包含某些动态数据。比如:你正在访问一个需要用户登录才能进一步操作的网站,你经常会在数据库中对用户进行这些操作:
- 记录用户正在执行的操作
- 将用户的某些信息添加到数据库中
- 检查用户的权限看其是否可以执行某项操作
- 等等
数据
我们来看两种方案:
- 在 Cookie 中存储用户 ID(abc123)
- 在 JWT 中存储用户 ID(abc123)
如果我们将 ID 存储在 Cookie 中,需要 6 个字节。如果将 ID 存储在 JWT 中(设置基本的请求头字段,以及一些其它信息),需要几百字节甚至更多。对于简单的会话控制,每个页面的请求就增大了几十倍。
假如你的网站每月有 10 万次的浏览器,就意味着要多开销几十兆的流量。听起来并不多,但日积月累也是不小一笔开销。实际上,许多人会在 JWT 中存储的信息会更多。
无论如何你需要操作数据库
如上所述,大多数需要用户登录的网站主要是 CRUD 操作(增查改删)生成动态内容。
在网站上使用 JWT,对于用户加载的几乎所有页面,都需要从缓存/数据库中加载用户信息,可能出现下列情况:
- 需要用户关键性信息查询(例如:判断用户账号是否有足够的资金完成交易?)
- 需要将一些信息保存进数据库(例如:用户相关的唯一信息,需要根据该信息对用户进行检索)
- 必须从缓存/数据库中查询完整的信息,方便网站生成完整的动态页面内容。
想想你的网站是否会遇到上述情形。这意味着大多数网站不适用 JWT 的无状态特性。为了解决这个问题,就需要 JWT 变得更大,而且需要使用 CPU 来计算签名,就会导致比传统会话慢许多。
其实,几乎每个 Web 框架支持在每次请求传入用户信息,这包括 Django,Rails,Express.js 等(如果有用到身份验证功能)。另外,如果你使用 Memcached/Redis 等缓存服务器对用户信息进行缓存,检索会变得非常快。
多余的签名
JWT 的卖点之一就是加密签名,由于这个特性,接收方得以验证 JWT 是否有效且被信任。
但是,其实在过去 20 年中几乎每一个框架对于普通会话 Cookie 都可以获得很好的加密签名处理。这意味着你可以获得与 JWT 完全一致的效果,况且大多数 Web 身份认证应用中,JWT 都会被存储到 Cookie 中,这就是说你有了两个层面的签名。
听着似乎很赞,但是没有任何优势,为此,你需要花费两倍的 CPU 开销来验证签名。对于有着严格性能要求的 Web 应用,这并不理想,尤其对于单线程环境。
更好的解决方案是什么?
如果你正在构建上述类型的网站,那么最好选择旧的,简单且安全的服务器端会话。而不是将用户 ID 存储到 JWT 中,然后再将 JWT 存储到 Cooike 中。只需将用户 ID 直接存储到 Cookie 中即可。
如果你的网站很受欢迎,有着大的访问量,可以将会话缓存到 Memcached/Redis,同时也有利于扩展你的服务。
什么时候使用 JWT?
JWT 虽然对于大多数网站都没有用,但是有几种情况它是很有用的。
如果你正在构建从服务器到服务器或客户端到服务器(如:移动应用 APP 或单页面应用)的 API 服务,那么使用 JWT 是非常明智的。比如:
- 你的客户端需要通过 API 进行身份验证,并返回 JWT
- 然后,客户端使用返回的 JWT 经过身份验证去请求其它的 API 服务
- 这些其它 API 服务通过客户端的 JWT 验证客户端是可信的,并且可以执行某些操作无需再次验证
对于这类 API 服务,JWT 非常适合,因为客户端需要频繁进行请求,并且权限是可控的,通常认证数据以无状态方式持久存在,不需要过多依赖用户信息。
如果你正在构建的应用类似单点登录或 OpenID Connect 认证,JWT 同样十分适合,就是实现一种通过第三方验证用户的方法。
总结
当你准备构建下一个网站时,只需要使用 Web 框架默认的身份认证功能即可,不需要再集成 JWT 方式。
原文地址:https://blog.csdn.net/weixin_41153791/article/details/82291144
你在用 JWT 代替 Session?的更多相关文章
- jwt、session、oauth 异同
1,jwt 和session机制 首先jwt 和session机制 都是用户认证的,oauth 不是 session 的流程: 1.用户向服务器发送用户名和密码. 2.服务器验证通过后,在当前对话(s ...
- ASP.NET Core Web Api之JWT VS Session VS Cookie(二)
前言 本文我们来探讨下JWT VS Session的问题,这个问题本没有过多的去思考,看到评论讨论太激烈,就花了一点时间去研究和总结,顺便说一句,这就是写博客的好处,一篇博客写出有的可能是经验积累,有 ...
- JWT与Session的比较
如今,越来越多的项目开始采用JWT作为认证授权机制,那么它和之前的Session究竟有什么区别呢?今天就让我们来了解一下. JWT是什么 定义 JSON Web Token(JWT)是一个开放标准(R ...
- JWT与Session比较和作用
1. JSON Web Token是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该 ...
- 不要把 JWT 用作 session
现在很多人使用 JWT 用作 session 管理,这是个糟糕的做法,下面阐述原因,有不同意见的同学欢迎讨论. 首先说明一下,JWT 有两种: 无状态的 JWT,token 中包含 session 数 ...
- 用户认证:基于jwt和session的区别和优缺点
背景知识: Authentication和Authorization的区别: Authentication:用户认证,指的是验证用户的身份,例如你希望以小A的身份登录,那么应用程序需要通过用户名和密码 ...
- jwt vs session 以rails 为例 (翻译部分)
原文地址:https://pragmaticstudio.com/tutorials/rails-session-cookies-for-api-authentication 普通方式: 令牌为基础的 ...
- 认证 协议 JWT OAuth Session Cookie
本文翻译自Auth-Boss. 如果有翻译的不恰当或不对的地方, 欢迎指出. 成为一个认证老司机, 了解网络上不同的身份认证方法. 本文档的目的是记录和编目Web上的身份验证方法.认证指的是创建一个系 ...
- 一文说通Jwt、Session、Cooike区别
JWT 全称是 JSON Web Token,是目前非常流行的跨域认证解决方案,在单点登录场景中经常使用到. 有些人觉得它非常好用,用了它之后就不用在服务端借助 redis 实现认证过程了,但是,还有 ...
随机推荐
- day65-test
目录 一.点击事件控制标签颜色 二.实现点击次数,变换页面标签的颜色 三.周期性实现颜色的旋转变色 练习题 一.点击事件控制标签颜色 1.有 红.黄.蓝 三个按钮,以及一个200x200矩形框box, ...
- python-基础-基础知识-变量-选择-循环
1 基础知识 1.1 注释的分类 1.2 变量以及类型 变量定义 num1 = 100 #num1就是一个变量,就好一个小菜篮子 num2 = 87 #num2也是一个变量 result = num1 ...
- HDFS读数据的过程
- mybatis学习:mybatis的注解开发CRUD操作
Dao层: public interface IUserDao { /** * 查询所有结果 * @return */ @Select("select * from user") ...
- K8s 学习者绝对不能错过的最全知识图谱(内含 56个知识点链接)
导读:Kubernetes 作为云原生时代的“操作系统”,熟悉和使用它是每名用户的必备技能.本篇文章概述了容器服务 Kubernetes 的知识图谱,部分内容参考了网上的知识图谱,旨在帮助用户更好的了 ...
- vmware 安装 黑群晖
先做一个启动盘 然后竟然启动不了 算了 不管了,去网上找个别人做好的吧 添加硬盘的时候,需要选择sata, 比如安装6.2需要这个版本的引导,就直接选中这个,因为我自己做的启动盘不管用,也不知道为嘛 ...
- Android的ADB学习笔记
1.ADB的常用命令 Pull命令:adb -e|-d pull {文件的路径} {获取文件路径} 2. 文件操作的基本命令 ls -al:显示当下目录下用户对文件的操作权限. = la -al ...
- web前端学习常用网址记录
jetbrains下载各种软件和试用 www.jetbrains.com www.jetbrains.com/idea php服务器下载 php文档查询 php.net webAPI网站(各种教程文档 ...
- visual studio code 调试reactjs
1.首先到visual studio code官网下载ide. 2.打开visual studio code,点击右侧菜单条的小图标 找到[Debugger for Chrome],并安装 3.打开c ...
- FreeMarker中<#include>和<#import>标签的区别
在使用freemarker作为前端页面模板的应用中,会有很多的freemarker模板页面,这些ftl会在不同的页面中重复使用,一是为了简化布局的管理,二是可以重复使用一些代码. 在freemarke ...