Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How JWT integrates Springboot

2025-04-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article will explain in detail how JWT integrates Springboot. The editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.

1. Based on JWT authentication

1.1 Certification process

First, the front end sends its user name and password to the back-end interface through the Web form. This process is typically a HTTP POST request. The recommended way is to use SSL encrypted transport (https protocol) to prevent sensitive information from being sniffed.

After the backend checks the user name and password successfully, it takes the user's id and other information as JWT Payload (payload), and signs it with the header after Base64 coding to form a JWT (Token). The resulting JWT is a string in the shape of lll.zzz.xxx. Token head.payload.singurater

The backend returns the JWT string to the front end as the result of a successful login. The front end can save the returned results on localStorage or sessionStorage. When logging out, the front end can delete the saved JWT.

The front end puts the JWT into the Authorization bit in the HTTP Header on each request. (resolve XSS and XSRF issues) HEADER

The backend checks whether it exists, such as verifying the validity of the JWT. For example, check that the signature is correct; check that the Token is out of date; and check that the recipient of the Token is yourself (optional).

After the verification is passed, the backend uses the user information contained in the JWT to perform other logical operations and return the corresponding results.

1.2 JWT advantage

Compact: can be sent through the URL,POST parameter or in HTTP header, because the amount of data is small and the transmission speed is fast.

Self-contained: the load contains all the information needed by users, avoiding multiple queries to the database

Because Token is stored on the client side in the form of JSON encryption, JWT is cross-language and is supported in principle in any web form

There is no need to save session information on the server, which is especially suitable for distributed micro-services.

1.3 what is the structure of JWT

Token string = = > header.payload.singnature token

Token composition

Header (Header)

Payload (Payload)

Signature (Signature)

Therefore, the JWT usually looks like this: xxxxx.yyyyy.zzzzz Header.Payload.Signature

Header

The header usually consists of two parts: the type of token (that is, JWT) and the signature algorithm used, such as HMAC SHA256 or RSA. It uses Base64 coding to make up the first part of the JWT structure.

Note: Base64 is a kind of coding, that is, it can be translated back to its original form. It is not an encryption process.

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

Payload

The second part of the token is the payload, which contains the declaration. A declaration is a declaration about entities (usually users) and other data. Similarly, it uses Base64 coding to make up the second part of the JWT structure

{"sub": "1234567890", "name": "John Doe", "admin": true}

Signature

The first two parts are encoded using Base64, that is, the front end can unlock the information inside. Signature needs to use the encoded header and payload as well as a key we provide, and then sign using the signature algorithm specified in header (HS256). The function of signature is to ensure that JWT has not been tampered with, such as: HMACSHA256 (base64UrlEncode (header) + "." + base64UrlEncode (payload), secret)

Signed item

The last step of signing is actually signing the header and payload content to prevent the content from being tampered with. If someone decodes the header and the payload, modifies it, then encodes it, and finally adds the previous signature combination to form a new JWT, then the server will determine that the signature formed by the new header and payload is different from the signature attached to the JWT. If you want to sign the new header and payload, the signature will be different if you don't know the key used when the server is encrypted.

Information security issues

Here you are bound to ask a question: Base64 is a kind of coding, is reversible, then my information will not be exposed?

Right. Therefore, in JWT, you should not add any sensitive data to the payload. In the above example, we are transmitting the user's User ID. This value is not really sensitive and is generally known to be safe. But things like passwords can't be put in JWT. If you put the user's password in JWT, then a malicious third party can quickly know your password through Base64 decoding. Therefore, JWT is suitable for passing some non-sensitive information to Web applications. JWT is also often used to design user authentication and authorization systems, and even

Realize the single sign-on of Web application.

two。 Use JWT

Introduce dependency

Com.auth0 java-jwt 3.4.0

Generate token

@ Testvoid contextLoads () {HashMap map = new HashMap (); Calendar instance=Calendar.getInstance (); instance.add (Calendar.SECOND,200) / / get token String token = JWT.create (). WithHeader (map) / / header. By default, you can not write .withClaim ("userId", 23) .withClaim ("username", "xpp") / / palyload .withExpiresAt (instance.getTime ()) / / specify the expiration time of the token. Sign (Algorithm.HMAC256 ("xpp@ll")); / / sign, specify the key System.out.println (token);}

Generate the result

EyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Mzc5MDM2OTksInVzZXJJZCI6MjMsInVzZXJuYW1lIjoieHBwIn0.dnWldEBILZpt7Upz762VcMm-uTU9HI5jK-AHk3XyX0s

Parse data based on tokens and signatures

@ Testpublic void test () {/ / create verification object JWTVerifier jwtVerifier = JWT.require (Algorithm.HMAC256 ("xpp@ll")) .build (); / verify token DecodedJWT verify = jwtVerifier.verify ("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2Mzc5MDM2OTksInVzZXJJZCI6MjMsInVzZXJuYW1lIjoieHBwIn0.dnWldEBILZpt7Upz762VcMm-uTU9HI5jK-AHk3XyX0s"); / / get information stored in palyload Date expiresAt = verify.getExpiresAt (); System.out.println (expiresAt); System.out.println (verify.getClaim ("userId"). AsInt ();}

Common abnormal information

SignatureVerificationException: signature inconsistency exception

TokenExpiredException: token expiration exception

AlgorithmMismatchException: algorithm mismatch exception

InvalidClaimException: invalid payload exception

3. Integrate Springboot

Introduce dependency

Com.auth0 java-jwt 3.4.0 org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3 org.projectlombok lombok 1.18.12 com.alibaba druid 1.1.19 mysql mysql-connector-java 5.1.38

Configuration

Server.port=8989spring.application.name=jwtspring.datasource.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/jwt?characterEncoding=UTF-8spring.datasource.username=rootspring.datasource.password=rootmybatis.type-aliases-package=com.baizhi.entitymybatis.mapper-locations=classpath:com/baizhi/mapper/*.xmllogging.level.com.baizhi.dao=debug

Database table

DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (`id` int (11) NOT NULL AUTO_INCREMENT COMMENT 'primary key', `name` varchar (80) DEFAULT NULL COMMENT 'username', `password` varchar (40) DEFAULT NULL COMMENT 'user password', PRIMARY KEY (`id`) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

Entity class

@ Data@Accessors (chain=true) public class User {private String id; private String name; private String password;}

Develop DAO interface and mapper.xml

@ Mapperpublic interface UserDAO {User login (User user);} select * from user where name=# {name} and password = # {password}

Develop Service interfaces and implementation classes

Public interface UserService {User login (User user); / / login interface} @ Service@Transactionalpublic class UserServiceImpl implements UserService {@ Autowired private UserDAO userDAO; @ Override @ Transactional (propagation = Propagation.SUPPORTS) public User login (User user) {User userDB = userDAO.login (user); if (userDB failed null) {return userDB;} throw new RuntimeException ("login failed ~");}}

Write JWT utility classes

/ * * @ Auther: xppll * @ Date: 13:25 on 2021-11-26 * / public class JWTUtils {/ / key private static final String TOKEN = "xpp@ll"; / * generate information passed by token (head.playload.sing) * * @ param map users, such as id * @ return * / public static String getToken (Map map) {Calendar instance = Calendar.getInstance () / / set 7-day expired instance.add by default (Calendar.DATE, 7); / / create jwt builder JWTCreator.Builder builder = JWT.create (); / / payload map.forEach ((k, v)-> {builder.withClaim (k, v);}) / / specify token expiration time String token = builder.withExpiresAt (instance.getTime ()) / / sign, pass in the encryption salt .sign (Algorithm.HMAC256 (TOKEN)); return token } / * verify the validity of token * * @ param token * / public static void verify (String token) {JWT.require (Algorithm.HMAC256 (TOKEN)) .build () .verify (token) } / * method for obtaining token information * * @ param token * @ return * / public static DecodedJWT getTokenInfo (String token) {DecodedJWT verify = JWT.require (Algorithm.HMAC256 (TOKEN)) .build () .verify (token); return verify;}}

Develop controller

/ * * @ Auther: xppll * @ Date: 14:07 * / @ RestController@Slf4jpublic class UserController {@ Autowired private UserService userService; @ GetMapping ("/ user/login") public Map login (User user) {Map map = new HashMap (); try {User userDB = userService.login (user); / / to store payload Map payload = new HashMap () Payload.put ("id", userDB.getId ()); payload.put ("name", userDB.getName ()); / / generate JWT token String token = JWTUtils.getToken (payload); map.put ("state", true); map.put ("msg", "success") / / successfully returned token information map.put ("token", token);} catch (Exception e) {map.put ("state", false); map.put ("msg", e.getMessage ());} return map;}}

Database add test data startup project

Simulate login failure through postman

Login is simulated successfully through postman

Write a test interface

@ PostMapping ("user/test") public Map test (String token) {/ / verified by the interceptor, token verification succeeded Map map = new HashMap (); map.put ("state", true); map.put ("msg", "request successful!") ; return map;}

Validate toke using interceptor

/ * * @ Auther: xppll * @ Date: 15:20 * / @ Componentpublic class JWTInterceptor implements HandlerInterceptor {@ Override public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {/ / get the token stored in the request header token String token = request.getHeader ("token"); Map map = new HashMap (); try {/ / verify token JWTUtils.verify (token) Return true;} catch (SignatureVerificationException e) {e.printStackTrace (); map.put ("msg", "invalid signature");} catch (AlgorithmMismatchException e) {e.printStackTrace (); map.put ("msg", "token algorithm inconsistency");} catch (TokenExpiredException e) {e.printStackTrace () Map.put ("msg", "token expiration");} catch (Exception e) {e.printStackTrace (); map.put ("msg", "token invalid");} map.put ("state", false); / / convert map to json and return to the front end String json = new ObjectMapper (). WriteValueAsString (map) Response.setContentType ("application/json;charset=utf-8"); response.getWriter () .print (json); return false;}}

Make the interceptor effective

/ * * @ Auther: xppll * @ Date: 15:28 on 2021-11-26 * / @ Configurationpublic class InterceptorConfig implements WebMvcConfigurer {@ Autowired private JWTInterceptor jwtInterceptor; @ Override public void addInterceptors (InterceptorRegistry registry) {registry.addInterceptor (jwtInterceptor) / / other interfaces require token authentication, interceptor intercepts .addPathPatterns ("/ user/test") .recipdePathPatterns ("/ user/login") }} this is the end of the article on "how JWT integrates Springboot". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report