小程序 jwt
JSON Web Tokens have become the favorite choice among modern developers when implementing user authentication. JWT’s popularity is clearly justified by what it brings to application development. In this post, we are looking deep into JWTs and why they stand out among other authentication options, as well as what you should be concerned about when using them.
在实现用户身份验证时,JSON Web令牌已成为现代开发人员中的首选。 JWT的普及显然可以通过它为应用程序开发带来的好处来证明。 在本文中,我们将深入研究JWT,以及为什么它们在其他身份验证选项中脱颖而出,以及使用它们时应注意的事项。
什么是JWT令牌? (What is a JWT token?)
A JWT is a self-contained method that can be used securely transmit data between two endpoints. JWTs are most commonly used for user authentication. They can also be used to securely exchange information. In this post, we are covering how JWTs are used for user authentication. However, information exchange using JWT follows roughly the same steps as user authentication.
JWT是一种独立的方法,可用于在两个端点之间安全地传输数据。 JWT最常用于用户身份验证。 它们还可以用于安全地交换信息。 在本文中,我们将介绍如何使用JWT进行用户身份验证。 但是,使用JWT进行信息交换的步骤与用户身份验证大致相同。
The authentication process involving JWTs follows these steps. When a user first logs into the application, system backend issues a JWT to the user and sends it to the client-side. This token contains a special signature that validates the token as a one issued by the system. The client stores the token in the browser and sends it with every request to the server, where the token is used to verify the user’s authentication.
涉及JWT的身份验证过程遵循以下步骤。 当用户首次登录到应用程序时,系统后端向用户发出JWT并将其发送到客户端。 该令牌包含一个特殊签名,该签名将令牌验证为系统发行的令牌。 客户端将令牌存储在浏览器中,并将其与每个请求一起发送到服务器,服务器使用该令牌来验证用户的身份验证。
A JWT consists of 3 strings separated by periods. The 3 of them are the header, payload, and the signature. Follows is an example JWT token made of these 3 parts.
一个JWT由3个由句点分隔的字符串组成。 它们中的3个是标头,有效负载和签名。 以下是由这三个部分组成的示例JWT令牌。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJteXdlYnNpdGUuY29tIiwiaWF0IjpudWxsLCJleHAiOjUxNDM3ODA4MDAwLCJhdWQiOiIiLCJzdWIiOiIiLCJpZCI6IjEyMzQ1OTEiLCJuYW1lIjoiTWFyeSBQb3BwaW5zIiwicm9sZSI6ImVkaXRvciJ9.LYKHdyKj6SnxYaRZH_ZhiW6yk31zaBQehYm4BgawH_o
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/bccbb0dcc391f1332f62c826e9d1ba9b.png)
Let’s see what each of these parts contributes to the overall makeup of the token.
让我们看看这些部分中的每一个对令牌整体结构的贡献。
标头 (Header)
JWT header contains metadata about the token in JSON format. Two fields present in the header are alg and typ. ’alg’ specifies the algorithm used to sign the token when generating the signature, which we will talk about in a moment. ’typ’ specifies the type of the token, which is ’JWT’. A typical token header is shown in the following example.
JWT标头包含有关JSON格式令牌的元数据。 标头中存在两个字段:alg和typ。 “ alg”指定生成签名时用于对令牌进行签名的算法,我们将在稍后讨论。 “ typ”指定令牌的类型,即“ JWT”。 以下示例显示了典型的令牌头。
{
"alg": "RS256",
"typ": "JWT"
}
Here, the header states the algorithm used to sign the token is RS256.
在此,标头指出用于对令牌进行签名的算法为RS256。
The header is stored as the first part of the token after being encoded in base64url.
标头被编码为base64url后,被存储为令牌的第一部分。
有效载荷 (Payload)
The payload of a JWT stores information about the token and any other entity in JSON format. Usually, a JWT used for authentication stores some crucial information about the user, such as the user ID and user role. Token storing user information usually looks like this.
JWT的有效负载以JSON格式存储有关令牌和任何其他实体的信息。 通常,用于身份验证的JWT存储有关用户的一些关键信息,例如用户ID和用户角色。 存储用户信息的令牌通常如下所示。
{
"id": "1234591",
"name": "Mary Poppins",
"role": "editor"
}
These JSON fields stored in the payload are known as claims.
存储在有效负载中的这些JSON字段称为声明。
In addition, there are some claims that are defined by the JWT standard. It’s not necessary to include all these claims in a JWT, but including at least some of them will be beneficial in most situations. Here are a few standard claims that we can use.
此外,JWT标准还定义了一些声明。 不必将所有这些声明包括在JWT中,但是在大多数情况下包括其中至少一些将是有益的。 这是我们可以使用的一些标准声明。
- iss: Defines the issuer of the token. iss:定义令牌的发行者。
- exp: Provides an expiration time to the token. Once this expiration time is passed, the token is no longer valid. exp:提供令牌的到期时间。 一旦超过此到期时间,令牌将不再有效。
- aud: Defines the audience of the token. aud:定义令牌的受众。
- iat: Stores the time the token was issued at. iat:存储令牌发布的时间。
Let’s see how a payload with some standard claims looks like.
让我们看看带有一些标准声明的有效负载的样子。
{
"id": "1234591",
"name": "Mary Poppins",
"role": "editor",
"iss": "mywebsite.com",
"exp": 3600
}
The payload of a JWT can include as many fields of information as you want, but it’s recommended to keep the size as small as possible. Also, you should not store sensitive information like user passwords in the payload since it is not encrypted. It’s simply encoded in base64url encoding.
JWT的有效负载可以包含所需的尽可能多的信息字段,但是建议将其大小保持尽可能小。 同样,您不应在有效负载中存储敏感信息,例如用户密码,因为该信息未加密。 它只是以base64url编码进行编码。
签名 (Signature)
The last part of a JWT token, the signature, is a Message Authentication Code that is used to verify the token was not modified or generated by an outsider except the authorized application servers.
JWT令牌的最后一部分(签名)是消息身份验证代码,用于验证令牌未由授权应用服务器以外的外部人员修改或生成。
Signature is generated by signing the combined JWT header and payload using an encryption algorithm and a secret stored in the server. Only someone who has the token’s header and payload and the secret can generate a sign accepted by the server. So, it is important to use a strong secret to encrypt tokens and securely store it in the server.
通过使用加密算法和存储在服务器中的机密对组合的JWT头和有效负载进行签名来生成签名。 只有拥有令牌头,有效负载和机密的人才能生成服务器接受的签名。 因此,使用强秘密对令牌进行加密并将其安全存储在服务器中非常重要。
If we use a symmetric algorithm like HMAC SHA-256, the server issuing the JWT and the server validating the JWT should have secure access to the secret. If an asymmetric algorithm like RS256 is used, we can use a public-private key system, where a private key is used to sign the token and a public key is used to validate it.
如果我们使用类似HMAC SHA-256的对称算法,则发出JWT的服务器和验证JWT的服务器应该可以安全地访问机密。 如果使用非对称算法(例如RS256),则可以使用公私钥系统,其中私钥用于对令牌进行签名,公钥用于对其进行验证。
As you have already guessed, the signature is the most crucial part of a JWT token. It keeps unauthenticated sources out of the application and keeps everything secure. When the issued JWT is sent back to the server with every request from the client-side, the server checks the signature to validate that it’s a token issued by the system itself and then proceed to serve the client request.
正如您已经猜到的,签名是JWT令牌中最关键的部分。 它将未经身份验证的源排除在应用程序之外,并确保所有内容的安全。 当发出的JWT与客户端发出的每个请求一起发送回服务器时,服务器将检查签名以确认它是系统本身发出的令牌,然后继续处理客户端请求。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/64b82619d12dadaa9c5fce94878f7f42.png)
JWT有什么特别之处? (What is so special about JWT?)
As we got to know the makeup of a JWT token, you might have been thinking about what makes it so special compared to other authentication methods, especially session-based authentication.
当我们知道JWT令牌的组成时,您可能已经在考虑与其他身份验证方法(尤其是基于会话的身份验证)相比,它为何如此特别。
The most important characteristic of JWT that makes it special is its statelessness. We saw what sort of data can be stored in a JWT in the previous section, and all the data that are needed to verify the token and identify the user are stored in the token itself. There is no need to maintain any record of the token in the server, like store the token in a database as we do with sessions. This makes JWTs stateless.
JWT使其与众不同的最重要特征是其无状态。 在上一节中,我们了解了可以在JWT中存储什么样的数据,并且验证令牌和标识用户所需的所有数据都存储在令牌本身中。 无需在服务器中维护令牌的任何记录,就像在会话中一样将令牌存储在数据库中一样。 这使得JWT无状态。
This stateless nature gives us the biggest benefit that comes with JWTs: The server that issues the JWT and the server that validates it does not have to be the same. One server can issue JWTs and carry out authentication tasks, while the other server that implements application logic can validate the JWT independent of the first server.
这种无状态的特性为我们带来了JWT的最大好处:发出JWT的服务器和验证JWT的服务器不必相同。 一台服务器可以发出JWT并执行身份验证任务,而另一台实现应用程序逻辑的服务器可以独立于第一台服务器验证JWT。
In the age of API backends and microservices-architecture applications, this allows the developers to delegate all authentication tasks to one server while the others implement application logic, and decouple the system as much as possible.
在API后端和微服务架构应用程序时代,这使开发人员可以将所有身份验证任务委托给一台服务器,而其他服务器则执行应用程序逻辑,并尽可能地使系统脱钩。
When JWT issuing and validating is carried out by separate servers, using a public-private key system is the best approach to take. In this case, the private key should be stored securely in the authentication server.
当JWT的发布和验证由单独的服务器执行时,使用公私钥系统是最好的方法。 在这种情况下,应将私钥安全地存储在身份验证服务器中。
如何将JWT令牌从客户端发送到服务器,反之亦然? (How to send JWT tokens from client-side to the server and vice-versa?)
When sending the JWT back and forth between the server and the client, we can send it along with the Authorization HTTP header. However, sending tokens over HTTP connections makes them susceptible to Man-In-The-Middle (MITM) attacks and stolen tokens. Therefore, it is essential to use secure HTTP connections when using JWTs.
在服务器和客户端之间来回发送JWT时,我们可以将其与Authorization HTTP标头一起发送。 但是,通过HTTP连接发送令牌会使它们容易受到中间人(MITM)攻击和令牌被盗的影响。 因此,在使用JWT时必须使用安全的HTTP连接。
Another problem with sending the token in the HTTP header is, in this approach, the token is usually stored in the local storage of the client-side browser. This exposes the tokens to being stolen using Cross-Site Scripting (XSS) attacks.
在HTTP标头中发送令牌的另一个问题是,采用这种方法时,令牌通常存储在客户端浏览器的本地存储中。 这使令牌很容易被跨站点脚本(XSS)攻击所窃取。
As a solution to this, you can send the token inside a cookie instead of inside the Authorization header. It’s essential to set HttpOnly and secure flags of the cookie to prevent attackers from stealing tokens using XSS attacks.
作为解决方案,您可以在Cookie内而不是在Authorization标头内发送令牌。 必须设置HttpOnly并保护cookie的标志,以防止攻击者使用XSS攻击窃取令牌。
使您的JWT令牌过期 (Expire your JWT tokens)
If in some way a JWT token is stolen by a third-party, they can use the stolen token to access the application and gain the token owner’s privileges. As a solution to this problem, we can set a short expiration time for the JWTs. This way, even if an attacker steals a token, they cannot make use of it for a time long enough to make an undesirable impact.
如果JWT令牌以某种方式被第三方窃取,则他们可以使用所窃取的令牌来访问应用程序并获得令牌所有者的特权。 作为此问题的解决方案,我们可以为JWT设置较短的到期时间。 这样,即使攻击者窃取了令牌,他们也无法在足够长时间内使用令牌以产生不良影响。
We can set the exp claim inside the payload to give a short expiration time to the token. However, this action does not eliminate the threat of stolen tokens, just reduces the chances of it leading to a serious attack.
我们可以在有效负载中设置exp声明,以使令牌有较短的到期时间。 但是,此操作并不能消除令牌被盗的威胁,只是减少了导致严重攻击的机会。
In real-world applications, setting a short expiration time to JWTs is not as simple as it sounds. If we created tokens that expire after ten minutes of creation, it will drastically reduce the user experience of your application’s users. How likely are the users to tolerate having to re-login every 10 minutes they spend on your application?
在实际应用中,为JWT设置短的到期时间并不像听起来那样简单。 如果我们创建的令牌在创建十分钟后过期,则将大大降低应用程序用户的用户体验。 用户在应用程序上每花10分钟忍受一次重新登录的可能性有多大?
But there is a solution to this: refresh tokens.
但是有一个解决方案:刷新令牌。
刷新令牌-它们是什么? (Refresh tokens — what are they?)
Since asking the users to log in again after every time a JWT token expires within a short time is not a good solution, developers have found a solution to this in refresh tokens.
由于每次JWT令牌在短时间内过期后要求用户重新登录都不是一个好的解决方案,因此开发人员已在刷新令牌中找到了解决方案。
The refresh token is a JWT token with a longer expiration time. It is used to issue a new access token, which is also a JWT token but with a shorter expiration time, every time the old access token expires.
刷新令牌是具有更长到期时间的JWT令牌。 每次旧的访问令牌到期时,它都用于发布新的访问令牌,它也是一个JWT令牌,但具有较短的到期时间。
In this situation, the access token is the token that is sent back and forth between the client and the server and has a short expiration time. However, when the access token expires within a short time, instead of asking the user to log in again, the server uses the refresh token to generate a new access token. Refresh token stores data needed to create a new access token.
在这种情况下,访问令牌是在客户端和服务器之间来回发送的令牌,并且具有较短的到期时间。 但是,当访问令牌在短时间内过期时,服务器将使用刷新令牌来生成新的访问令牌,而不是要求用户再次登录。 刷新令牌存储创建新访问令牌所需的数据。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/df7eed3e603fc4d7f27eb6721fdbe56e.png)
Since refresh token has a long expiration time and it is not being passed to the client-side in any case, we should store them in a backend database. If an attacker somehow gets access to a refresh token, it’s a serious security threat to the system and the owner of the refresh token given their long expiration time. So, refresh tokens must be stored under maximum security measures.
由于刷新令牌的有效期很长,并且无论如何都不会传递给客户端,因此我们应该将其存储在后端数据库中。 如果攻击者以某种方式获得了刷新令牌的访问权限,则由于其过期时间较长,这对系统和刷新令牌的所有者构成了严重的安全威胁。 因此,刷新令牌必须以最大的安全措施存储。
A user first receives a refresh token when they login to the system. Then, the token is stored in a secure database. Issuing a new refresh token every time a new access token is generated is something you can do to ensure that the security impact of stolen refresh tokens is low.
用户登录系统时,首先会收到刷新令牌。 然后,令牌存储在安全数据库中。 您可以每次生成新的访问令牌时发出新的刷新令牌,以确保被盗的刷新令牌对安全的影响很小。
When a refresh token expires, the user has to log in to the application again and get a new refresh token.
当刷新令牌过期时,用户必须再次登录到应用程序并获取新的刷新令牌。
If JWT issuing and validating are handled by separate servers, it’s important to note that issuing access tokens using refresh tokens is a task handled by the authentication server.
如果JWT的发布和验证是由单独的服务器处理的,则需要注意的是,使用刷新令牌发布访问令牌是身份验证服务器处理的任务。
结论 (Conclusion)
JWT is a modern and robust solution to authenticating users and sharing sensitive information while not maintaining state. A JWT is made of three parts: header, payload, and signature. Despite the benefits of JWTs in modern application development, there are special measures we need to take to ensure the security of the tokens and user data. Sending JWTs in cookies instead of in the header, shortening their expiration time, and using refresh tokens to issue new access tokens are some of the security measures we can take to guarantee the security of our application, its users, and their data.
JWT是一种现代而强大的解决方案,用于在不维护状态的情况下验证用户身份并共享敏感信息。 JWT由三部分组成:标头,有效负载和签名。 尽管JWT在现代应用程序开发中有很多好处,但是我们仍然需要采取特殊措施来确保令牌和用户数据的安全性。 我们可以采取一些安全措施来保证应用程序,其用户及其数据的安全性,其中一些方法是通过Cookie而不是通过标头发送JWT,缩短其过期时间以及使用刷新令牌发布新的访问令牌。
In a follow-up post we are going to implement all it on an API.
在后续文章中,我们将在API上实现所有这些功能。
Thanks for reading!
谢谢阅读!
翻译自: https://levelup.gitconnected.com/a-brief-introduction-to-securing-applications-with-jwt-2004e9f6c829
小程序 jwt