Directory
- What is JWT
- The structure of the JWT
- Header
- Payload
- Signature
- The decoded JWT
- How does a JWT work?
- Using JWT in Java
- Introducing Dependencies
- JWT Service
- Generate JWT
- Decode JWT
- Verifying JWT
- Register/Login
- Verifying JWT
- Api
- Tail note
What is JWT
JWT (JSON Web Token) is an open standard (RFC 7519), which defines a compact and independent way to securely transfer information between systems using JSON as an object, and to ensure that the transmitted information is not tampered with.
JWT typically has two scenarios:
- Authorized. This is the most common scenario for JWT usage. Once a user logs in, each subsequent request will contain a JWT as the token for the user to access the resource.
- Information exchange. JWT can be used to securely transfer information between systems, and the features of JWT enable the receiver to verify that the received content has been tampered with.
This article discusses 1th, how to use JWT to implement authorization access to the API. This allows the API to be invoked only by authorized users.
The structure of the JWT
The JWT consists of three parts, separated by a .
split.
Header
The first part Header
is usually made up of two parts: the type of token, the JWT, and the encryption algorithm used.
{ "alg": "HS256", "typ": "JWT"}
Base64
After encryption, it becomes:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
In the second part Payload
, we can place the customized information, the expiration time, the issuer and so on.
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022}
Base64
After encryption, it becomes:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Signature
In the third part Signature
, it takes four pieces of information to calculate this signature:
Header
Algorithm information in the
Header
Payload
- A custom secret key
Once the JWT is accepted, the same information is used to calculate the signature again, compared to the signature in the JWT, and if not the same, the content in the JWT is tampered with.
The decoded JWT
The above three parts are encoded and then combined together to get a JWT.
It is important to note that thecontents of JWT are not encrypted, but simply Base64
encoded. in other words, once the JWT leaks, the information inside can be easily retrieved, so no sensitive information should be saved with JWT.
How does a JWT work?
- The application or client requests authorization from the authorization server. The authorization server here can be a separate application, or it can be integrated with the API in the same application.
- The authorization server returns a JWT to the application.
- The application puts the JWT into the request (usually in
HTTP
the head Authorization
)
- After the server receives the request, validates the JWT and executes the corresponding logic.
Using JWT in Java to introduce dependencies
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId></dependency>
A library called JJWT (Java JWT) is used here.
JWT Service Generation JWT
public String generateToken(String payload) { return Jwts.builder() .setSubject(payload) .setExpiration(new Date(System.currentTimeMillis() + 10000)) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }
- The expiration time is set to 10 seconds, so the generated JWT is validated only in 10 seconds.
- You need to provide a custom secret key.
Decode JWT
public String parseToken(String jwt) { return Jwts.parser() .setSigningKey(SECRET_KEY) .parseClaimsJws(jwt) .getBody() .getSubject(); }
- The signature of the JWT is checked when decoding, so a secret key is required.
Verifying JWT
public boolean isTokenValid(String jwt) { try { parseToken(jwt); } catch (Throwable e) { return false; } return true; }
JJWT
Does not provide a way to determine whether JWT is legal, but it throws an exception when decoding an illegal JWT, so it is possible to determine whether it is legal by catching an exception.
Register/Login
@GetMapping("/registration") public String register(@RequestParam String username, HttpServletResponse response) { String jwt = jwtService.generateToken(username); response.setHeader(JWT_HEADER_NAME, jwt); return String.format("JWT for %s :\n%s", username, jwt); }
- You need to provide a sign-up or login portal for users who have not yet acquired a JWT to get JWT.
- After obtaining the JWT in the response, the JWT is included in the subsequent request, which is placed in the requested header
Authorization
.
Verifying JWT
@Overridepublic void DoFilter (ServletRequest request, servletresponse response, Filterchain chain) throws IOException, servletexception {httpservletrequest httpservletrequest = (httpservletrequest) request; HttpServletResponse HttpServletResponse = (httpservletresponse) response; String JWT = Httpservletrequest.getheader (jwt_header_name); if (White_list.contains (Httpservletrequest.getrequesturi ())) {Chain.dofilter (request, response); } else if (Istokenvalid (JWT)) {Updatetoken (HttpServletResponse, JWT); Chain.dofilter (request, response); } else {httpservletresponse.senderror (httpservletresponse.sc_unauthorized); }} private void Updatetoken (HttpServletResponse httpservletresponse, String jwt) {string payload = Jwtservi Ce.parsetoken (JWT); String Newtoken = Jwtservice.generatetoken (payload); Httpservletresponse.setheader (Jwt_header_name, Newtoken); }
- Put the validation action in place so that the
Filter
other business code will not feel the presence of the JWT except the login entry.
- Place the login entry in
WHITE_LIST
, skipping validation of these portals.
- The JWT needs to be refreshed. If the JWT is legal, you should use the same
Payload
to generate a new JWT so that the new JWT will have a new expiration time and use this action to refresh the JWT in case it expires.
- If used
Filter
, then the flush operation will not be doFilter()
modified until after the call because it is called response
.
Api
private final static String JWT_HEADER_NAME = "Authorization"; @GetMapping("/api") public String testApi(HttpServletRequest request, HttpServletResponse response) { String oldJwt = request.getHeader(JWT_HEADER_NAME); String newJwt = response.getHeader(JWT_HEADER_NAME); return String.format("Your old JWT is:\n%s \nYour new JWT is:\n%s\n", oldJwt, newJwt); }
This is when the API is under the protection of JWT. The API can be completely unaware of the existence of a JWT, but it can also proactively acquire JWT and decode it to get the information in the JWT. As shown above.
Tail note
- The full demo can be found here: Github.com/beginner258/jwt-demo
- Reference: jwt.io/