JSON Web Tokens (JWT) — the only explanation you will ever need

news2025/1/10 0:15:10
本文摘抄自 Ariel Weinberger 博客
  JSON Web Tokens (JWT) — the only explanation you will ever need | by Ariel Weinberger | Medium

JSON Web Tokens (JWT) — the only explanation you will ever need

JSON Web Tokens are changing the world for the better. Acting as the shield of stateless and distributed architectures, JWTs are pretty amazing. But with great responsibility comes great confusion, and I’m here to help shed some light on this wonderful technology.

This article will be divided into two parts: Part 1 covering the JWT standard, and Part 2 being the juicy part, covering common use cases, techniques, misconceptions and frequently asked questions.

Introduction

Hello! My name is Ariel. Over the past years I have worked in various industries (FinTech, Sports, Entertainment, BioTech). I’ve love doing a bit of everything — front-end, back-end, ops and leadership.

Today I am Head of Engineering at Abcam. We support scientists across the globe in achieving amazing breakthroughs in Cancer Research, Alzheimer’s Disease Research and other biology-related matters.

Why do we need JSON Web Tokens (JWTs)?

I always believe that requirements come first. Understanding why we need JWTs rather than diving right into the explanation will surely help.

In the modern web, you will often have several parties communicating with each other. Certain features will naturally be restricted and require some sort of authorization mechanism.

Your typical front-end to back-end usage

The most shallow example would be a front-end application communicating with an API via HTTP requests. Using a JWT, you will be able to authorize the user. You could then take it one step further and use JWTs to perform role checks (for example, when a certain API route should only be available to admin users).

In distributed systems

JWTs are extremely useful in distributed systems and microservices architecture, utilising the Private-Public Key signing method. This method will save you a huge amount of requests and improve the overall scalability of your application. We will talk about that later on in this article.

The three components of a JSON Web Token

Part 1: The JWT Standard

JSON Web Token is a standard. A typical token will consist of a header, a payload and a signature. Let’s talk about each one of those and how they are utilised.

Header

The header contains metadata information about the JSON Web Token.

  • Algorithm (alg): The algorithm used to sign the token. This is useful for the attempted reproduction of the signature (we will talk about that later).
  • Type (typ): The type of the token. In the case of a JWT, this will always have the JWT value.

You will sometimes find extra headers that were added by the issuer. But the above two will most certainly always be there.

Payload

That’s what you’ve been waiting for. The payload will contain the claims of the token. There are several “recommended” standard fields that are defined in the JWT standard. Let’s talk about the most used ones:

  • Issuer (iss): The entity to generate and issue the JSON Web Token (for example, your authentication service or OAuth provider).
  • Subject (sub): The entity identified by this token. For example, if the token is used to authorize a user, sub could be the user ID.
  • Audience (aud): Target audience for this JWT. For example, if the token is intended to be used by your beta testers user pool, you could specify that as an audience. It is advised to reject tokens with no audience.
  • Expiry (exp): Specifies the timestamp (Unix) after which the token should not be accepted. We will talk about short-lived JWTs later on.
  • Issued at (iat): Specifies the date at which the token has been issued.

Now, these are the recommended ones. On top of those, you can feel free to add whatever extra fields you need.

For example, this would be a totally valid JWT payload:

{
"sub": "1dfee8d8-98a5-4314-b4ae-fb55c4b18845",
"email": "ariel@codingly.io",
"name": "Ariel Weinberger",
"role": "ADMIN",
"iat": 1598607423,
"exp": 1598607723
}

IMPORTANT: The payload of a JSON Web Token is, by default, decodable by anyone. In fact, you can paste any JWT into https://jwt.io and immediately see the claims.

Signature

Although we would like to believe that the magic of JWTs happens in the payload, it actually happens in the signature. This is probably the most commonly misunderstood part about JWTs.

Often times, people use the term “encrypt-decrypt” with JSON Web Tokens. You cannot decrypt the signature of a token. That is the idea behind the signature.

The signature is created from the encoded header, encoded payload, a secret (or private key, read further) and a cryptographic algorithm. All these four components allow the creation of a signature.

signature = Crypto(secret, base64(header), base64(payload))

And this is a sample signature:

jbcOUQ2bbiYlfVtprEkaT_S6Y6yQnBDOAKDHIHjvl7g

If you are thinking “that looks like gibberish”, you are absolutely correct. The signature looks like gibberish. But hey, this gibberish is unique and reproducible.

“Everyone can read my tokens! They can change the claims and grant themselves admin access!”

The first part is true. The second part isn’t. JSON Web Tokens are decodable by anyone. In fact, feel free to copy the following token:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxZGZlZThkOC05OGE1LTQzMTQtYjRhZS1mYjU1YzRiMTg4NDUiLCJlbWFpbCI6ImFyaWVsQGNvZGluZ2x5LmlvIiwibmFtZSI6IkFyaWVsIFdlaW5iZXJnZXIiLCJyb2xlIjoiVVNFUiIsImlhdCI6MTU5ODYwODg0OCwiZXhwIjoxNTk4NjA5MTQ4fQ.oa3ziIZAoVFdn-97rweJAjjFn6a4ZSw7ogIHA74mGq0

And paste it directly into https://jwt.io.

You can immediately see all the claims in this token. That is why you should never store sensitive information in the token (no, a user’s role is not sensitive — a password is).

Now you are probably wondering, what prevents people from tampering with the token? Well, the signature does!

When verifying a JSON Web Token, whatever client you use will take the headers and claims, then generate a signature. It will then compare the new signature with the old signature. JWT signatures are not decrypted but rather reproduced and then compared (JWT misconception #1). If you are familiar with the world of hashing, you should now feel at home.

So, somebody tampered with the claims and set their role to ADMIN. The JWT verification will fail as the signature does not match anymore (remember, the signature is generated using the original payload defined by the issuer — where the role is USER).

Generating and signing a new JSON Web Token won’t work for them either — as they (hopefully) don’t have access to the secret or private key you use to sign your tokens. If they do, you are in trouble.

Part 2: Common Misconceptions, FAQs and Techniques

We’ve discussed how JSON Web Tokens work. The value I hope to provide in this article is far beyond that. I hope you will be able to learn something new from this section where I talk about practical use cases, techniques and common misconceptions when using JSON Web Tokens.

JWTs as Passports

JWTs are often used as a user’s passport. All I need in order to send requests on your behalf is your JSON Web Token. Therefore, it is your (and the service provider’s) goal to ensure the token is kept safe from any impersonator.

Always make sure to serve your clients via a secure connection (HTTPS). This will protect you and your clients from man-in-the-middle attacks, as the connection is encrypted.

Note that this approach will not protect you from other types of attacks (XSRF, for example).

Short-lived JWTs and Invalidating Tokens

Short-lived tokens (tokens that expire quickly after they are issued) are highly advised. Some services have their tokens expire as soon as 5 minutes after issuing them.

After the token has expired, the auth server will issue a new access token (this action is called “token refresh”, explanation below) with the most up-to-date claim. For example, if the user role has changed from ADMIN to USER, having short-lived tokens will ensure the user’s token contains the most recent user role.

So to sum it up, short-lived tokens are useful for two main reasons:

  • If your token has been compromised, it will expire quickly after and that will limit the time window during which the attacker is able to use your token and perform operations on your behalf.
  • JWTs are stateless. You cannot invalidate such tokens (that is pretty much the only trade-off in using this type of token). Therefore, short-lived tokens are closest we can get to keeping strong consistency over stuff like user permissions and roles.

JWT Advantages and Should You Trust Your Tokens?

JWTs are stateless. That is a blessing and a curse. To my taste, mostly a blessing.

Why JWTs being stateless is awesome

JWTs are not meant to be stored in a database. In a distributed system, you might have several back-end services for different purposes and business domains. All these services need is a public key (more information on this below) and they can now verify tokens from incoming requests. There is no need to send a request to your auth server for every request (you have no idea how frequently I see this being done). This is a massive performance, resilience and scalability gain.

“But Ariel, why not introduce an API Gateway to check the tokens and route internal traffic to target services?”

You might as well do that. I have no strong opinion about this subject. What I can say, though, is that I always prefer to avoid single points of failure and bottlenecks. However, there are technologies such as KeyCloak that handle this at an ingress level with almost zero overhead.

Should I trust the claims in my token, at all times?

I will leave this decision to you. In general, I put full trust in my JSON Web Tokens and I consider the claims in my tokens to be the source of truth unless the operation is potentially destructive (changing payment method, changing password or email, etcetera). In this case, you could ask the user for an extra factor such as their password.

If you find yourself involving your Auth Service frequently, ensuring permissions against the database for every single operation, you are using JSON Web Tokens wrong.

Refresh Tokens

Nicely bridging from the above section. Refresh Tokens are pretty much a must in every system that uses JWTs.

The way Refresh Tokens work is fairly simple. Upon initial authentication, the user will receive two tokens (note that the names might differ per auth provider):

  • Access Token: Your typical JSON Web Token that is sent with every request. Contains the user claim.
  • Refresh Token: This special kind of token is persisted in a database, mostly owned by an Authentication Service of some sort. This is often not a JWT — but rather a unique hash.

As we already know, the Access Token will be sent with every request (fetch blog posts, create blog post, add comment etcetera) and at some point the token will expired. Then, the front-end will send a refresh request with the refresh token. The auth server will generate a new Access Token (JWT) with the most up-to-date claims, and send it back to the user. The user will use this token until it’s expired, and then refresh again. Over and over.

Refresh tokens can be valid for months, and that is often the case. When the refresh token expires, the user will be signed out and need to authenticate again. Do you remember the last time you had to log into Facebook, Twitter etcetera?

Secret VS Private-Public Key (Keypair)

There are two ways to sign JSON Web Tokens. Let’s consider a very common distributed system where we have several services (Auth Service, Warehouse Service, Order Service and Notification Service).

Common Microservices Architecture

Secret

You could use any string as a secret (for example, dontUseThisSecret123##$%83), and the same secret will be used to verify the signature. However, if you choose to do so, please use a non-trivial secret that is hard to brute-force.

That works okay for monolithic systems. But what if you have several services that serve users? For example; Auth Service, Warehouse Service, Invoice Service, Notification Service and Order Service.

In this case, the Secret approach is seriously risky. All services will need to have access to the secret in order to verify the token. Which means:

  • All services will know the secret. That increases the risk of the secret being exposed or hijacked by an attacker. I mean, when you tell your friend a secret you don’t expect it to be spread around, right?
  • All services technically have the ability to create new tokens — whose responsibility is it to generate tokens? This can introduce semantic problems of ownership.

Key Pair (Public and Private Keys)

This is my favorite approach when working with JWTs. This utilizes a pair of keys — private and public.

Following this approach, the issuer of our token (Auth Service) will use a private key to sign the tokens (using RSA or ECSA algorithms). As the name implies, this key will be private and won’t be shared with any other service.

Any other service interested in verifying incoming tokens will have the public key. Public keys are able to verify tokens but not sign new ones. Therefore, the risks mentioned above are eliminated. There is absolutely no risk in exposing the public keys.

Using this approach, you could even let external parties verify the identity of your users. Which, in some cases, can actually be useful.

Where Should I Store The JSON Web Tokens?

This is probably the most common question you will see about JSON Web Tokens on Stackoverflow. I will try to touch it briefly, but would rather refer you to other external resources as I am no security expert.

You always have to remember that JWTs are passports. If somebody gets access to one of your user’s tokens, he/she can send requests on behalf of you. This is bad.

Storing tokens in Local Storage is incredibly popular because it’s comfortable. However, this is not the most secure way to do things. It’s very XSS (Cross-Site-Scripting) vulnerable.

Storing your tokens in a HttpOnly cookie (not a regular cookie) would be preferable. It would be better against XSS attacks, but still vulnerable to CSRF attacks. This can of course introduce annoying challenges in terms of CORS policies, but hey — it is security we’re dealing with here.

I advise you to learn more from this Stackoverflow answer.

What If I Want to Encrypt My Tokens Anyway?

In some cases you might want to apply an encryption over your token, to prevent hijackers from reading your claims. This is mostly common in server-to-server communication.

That is totally fine — feel free to apply whatever encryption you prefer over your token, as long as the receiving end can securely decrypt and view the token.

Either way, remember that performing communication over HTTPS is a must and will dramatically increase communication security.

Summary

This is my first post on Medium, and also my best attempt at sheding some light on the whole “JSON Web Token thing”. Hopefully this helped you. I would like to welcome any suggestions and extra information in the comments. I will do my best to keep this article up-to-date with recents developments and techniques.

___

Useful Resources

  • jwt.io by Auth0: documentation and interactive decoding of JSON Web Tokens
  • jsonwebtoken at NPM: my favorite library for dealing with JSON Web Tokens
  • JSON Web Token on Wikipedia
  • JSON Web Token (JWT) RFC by Internet Engineering Task Force (IETF)

Let’s Get in Touch

You are most welcome to follow me here on Medium. In addition, feel free to check out:

  • NestJS Zero to Hero — Modern TypeScript Back-end Development on Udemy (4.7 ⭐ with over 70,000 students)
  • Serverless Framework Bootcamp on Udemy (4.7 ⭐ with over 30,000 students)
  • My Twitter ProfileFollow me for free educational content and discounts.
  • My LinkedIn Profile: Let’s connect!
  • Feel free to contact me at ariel@codingly.io
Jwt
Web Development
Software Development
Nodejs
Security

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/440879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java程序员学前端-Vue2篇

Vue 2 1. Vue 基础 1) 环境准备 安装脚手架 npm install -g vue/cli-g 参数表示全局安装,这样在任意目录都可以使用 vue 脚本创建项目 创建项目 vue ui使用图形向导来创建 vue 项目,如下图,输入项目名 选择手动配置项目 添加 vue rou…

【Vue基础】element快速入门

一、知识点整理 1、安装Element UI组件库,在当前目录下,在命令行执行指令: npm install element -ui2.15.3 如果无法安装,执行以下指令: npm install --legacy-peer-deps element-ui --save 2、引入Element组件库 …

IT项目管理画图题【太原理工大学】

期末复习汇总,点这里!https://blog.csdn.net/m0_52861684/category_12095266.html?spm1001.2014.3001.5482 也不知道让画啥,随便猜一下吧。我觉得大概率是让画双代号网络图了,不是网络图我倒立,呃...还是算了吧&#…

氢原子光谱、类氢原子光谱和类氢离子光谱

一、氢原子光谱 (1)万分之五的差值 在文章“原子的波尔模型、能量量子化、光电效应、光谱实验、量子态、角动量”的第3.3节角动量量子化中,通过公式联立获得得里德伯常数要比经验获得的相差万分之五。 当然这时候有人会想是不是实验测得不准…

设计模式:创建者模式 - 适配器模式

文章目录 1.概述2.结构3.类适配器模式4.对象适配器模式5.应用场景6.JDK源码解析 - Reader 与 InputStream 1.概述 如果去欧洲国家去旅游的话,他们的插座如下图最左边,是欧洲标准。而我们使用的插头如下图最右边的。因此我们的笔记本电脑,手机…

中国人民大学与加拿大女王大学金融硕士——每一份投入和努力其实都有回声

有付出,就会有收获;有努力,就会有回报。当你愿意走出舒适区投入到再学习上,当你为了提升自身而努力后,你终将收获属于你的美好。在金融领域在职读研的我们,待拿到中国人民大学与加拿大女王大学金融硕士毕业…

zabbix配置钉钉机器人告警

1.在钉钉上创建一个钉钉群组 2.在群组中添加一个机器人 3.配置zabbix server调用钉钉接口的代码(使用python) 查看是否有python环境 python --version 找到zabbix 的AlertScriptsPath目录路径 cat /etc/zabbix/zabbix_server.conf|grep AlertScriptsPath 将调用钉钉接口的py…

51单片机(80951系列)引脚功能说明

一 AT89C51引脚图 1.0 中断 1.0.1 中断源 AT89C51一共有5个中断源 (1):外部中断0,外部中断请求信号由引脚输入,低电平或下降沿有效,中断请求标志位IE0。 (2):外部中断1…

Hive-hive核心面试范围题目整理(数据倾斜、外部表内部表、分区分桶、行转列等)

1 hive的优缺点 优点 SQL减少MR的开发难度使用于实时性不高的数据分析场合优势处理大数据自定义函数 缺点 Hql表达能力优先:迭代式算法? 处理延迟效率较低,小数据的时候,不如传统数据库 2 对hive的了解 优点本质&#xff1…

pymysql详解——通过Python连接Mysql数据库

pymysql详解——通过Python连接Mysql数据库 pymysql是可用于连接mysql数据库,且能够提供mysql与python窗口交互创立通道的工具库。可以通过创建引擎,建立游标直接通过python编程实现mysql数据库操作。在开发和分析可形成线性脚本。是广泛使用的库。 连…

计算机组成原理——第七章输入输出系统(上)

如若来世再相见,半点朱唇尽我尝 文章目录 7.1.1 输入输出系统和IO控制方式7.1.2 外部设备7.2 IO接口7.3.1 程序查询方式流程图 7.1.1 输入输出系统和IO控制方式 i/O接口是一个电子部件,会被集成与主板中,而I/O设备则是你看得见摸得着的那些设…

O(1) 时间复杂度的抽奖算法 - The Alias Method

0 背景 在营销等场景下,有种常见的玩法,即抽奖,不论前端抽奖界面如何炫酷,底层抽奖组件具有一致性。本文不讨论奖池的抽取规则、奖池奖品配置、奖池切换、抽奖机会、奖品扣减和发放、告警和降级等,主要聚焦于抽奖算法…

Nginx之TCP/UDP反向代理

Nginx从1.9.13起开始发布ngx_stream_core_module模块不仅能支持TCP代理及负载均衡,其实也是支持UDP协议的。 1.Nginx下载 wget http://nginx.org/download/nginx-1.24.0.tar.gz 2.Nginx安装 #yum -y install proc* openssl* pcre* # tar -zxvf nginx-1.24.0.tar.gz #cd n…

【Docker学习三部曲】—— 核心篇

容器数据卷 基本概念 容器数据卷是 Docker 中用于持久化存储容器数据的一种解决方案它允许容器中的数据在容器重新创建或迁移时得以保留,而不会丢失数据卷可以看作是 Docker 主机和容器之间的一个共享目录容器可以将数据写入数据卷,而这些数据将储存在…

【Jpom】docker-compose 部署 RabbitMQ 3.11.X (包含延迟队列插件)

文章目录 前言参考目录前置准备系统版本软件版本 部署步骤1、Jpom 配置节点信息2、Dockerfile 文件3、插件上传4、修改 docker-compose.yml5、构建 Dockerfile(可选)6、执行 docker-compose 编排7、Jpom 查看 Docker8、登录 RabbitMQ9、直接执行 docker-…

OrCAD原理图检查

OrCAD原理图检查 FPGA或处理器芯片原理图封装检查OrCad元件Part Reference与Reference位号不同检查所有器件是否与CIS库元件匹配用CIS库中的元器件替换已存在器件方法1方法2 DRC检查修改页码Annotate重排位号利用Intersheet References功能进行off-page索引检查封装、厂家、型号…

[数据结构 - C语言] 顺序表

目录 1、线性表 2、顺序表 2.1 顺序表的概念 2.2 接口 3、接口实现 3.1 初始化 3.2 销毁 3.3 容量检测 3.4 打印数据 3.5 顺序表的头插 3.6 顺序表的尾插 3.7 顺序表的头删、尾删 3.8 顺序表查找 3.9 指定位置插入数据 1、线性表 线性表(linear list&…

认识HTTPS以及了解HTTPS的加密过程

目录 简单认识HTTPS: 运营商劫持: 加密的理解: HTTPS的工作过程: 对称加密: 非对称加密: 中间人攻击 证书 简单认识HTTPS: HTTPS 也是一个应用层协议。是在 HTTP 协议的基础上引…

逆向-还原代码之(*point)[4]和char *point[4] (Interl 32)

// source code #include <stdio.h> #include <string.h> #include <stdlib.h> /* * char (*point)[4] // 数组指针。 a[3][4] // 先申明二维数组,用它来指向这个二维数组 * char *point[4] // 指针数组。 a[4][5] // 一连串的指针…

客快物流大数据项目(一百一十六):远程调用 Spring Cloud Feign

文章目录 远程调用 Spring Cloud Feign 一、​​​​​​​简介