Springboot integrates JWT to realize token verification and token logoff

Time:2021-12-8

Original address:https://www.byteblogs.com/article/164

JWT official website:[https://jwt.io/][https_jwt.io]

GitHub address of JWT (Java version):[https://github.com/jwtk/jjwt][https_github.com_jwtk_jjwt]

What is JWT

Json web token (JWT), is a method based on which declarations are passed between network application environmentsJSONOpen standard for (RFC 7519)A concise, self-contained method is defined for communication between two partiesJSONThe form of object can transfer information safely.Because of the existence of digital signatures, this information is credible,JWT can useHMACAlgorithm orRSAThe public-private key pair is signed.

JWT request process

Springboot integrates JWT to realize token verification and token logoff

1. The user sends a post request using the account and face;

2. The server uses the private key to create a JWT;

3. The server returns this JWT to the browser;

4. The browser sends the JWT string in the request header to the server like a request;

5. The server verifies the JWT;

6. Return the response resource to the browser.

Main application scenarios of JWT

Identity authentication in this scenario, once the user completes login, JWT is included in each subsequent request,It can be used to verify user identity and access rights to routes, services and resources.Because its overhead is very small, it can be easily transmitted in different domain name systemsSingle sign on (SSO)This technology is widely used in. Information exchange it is a very secure way to use JWT to encode data between the two sides of communication,Because its information is signed, it can ensure that the information sent by the sender is not forged.

advantage

1. Compact: you can useURLPOSTParameter or inHTTP headerSend, because the amount of data is small and the transmission speed is fast

2. Self contained: the load contains the information required by all users, avoiding multiple queries to the database

3. BecauseTokenSoJSONThe encrypted form is saved on the client, soJWTIt is cross language and is supported by any web form in principle.

4. There is no need to save session information on the server, which is especially suitable for distributed microservices.

`

Structure of JWT

JWT is composed of three pieces of information, which are used as text.Together, the JWT string is formed.

Like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

JWT consists of three parts:

Header header (the header contains the metadata of the token and contains the type of signature and / or encryption algorithm)

Payload load (similar to items carried on an aircraft)

Signature signature / visa

Header

The header of JWT carries two parts of information: token type and encryption algorithm.

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

Declaration type: here is JWT

Algorithm for declaring encryption: HMAC sha256 is usually used directly

Encryption algorithm is a one-way function hash algorithm. The common ones are MD5, Sha and HAMC.

MD5(message-digest algorithm 5)(information summary algorithm) abbreviation, widely used in encryption and decryption technology, commonly used in file verification. Check? No matter how large the file is, a unique MD5 value can be generated after MD5

Sha (secure hash algorithm), digital signature and other important tools in cryptography applications, with security higher than MD5

HMAC (Hash Message Authentication Code), hash message authentication code, key based hash algorithm authentication protocol. The public function and key are used to generate a fixed length value as the authentication identifier, which is used to authenticate the integrity of the message. Commonly used for interface signature verification

Payload

Payload is the place where valid information is stored.

Valid information consists of three parts

1. Declaration registered in the standard

2. Public statements

3. Declaration of private ownership

Declaration registered in the standard (recommended but not mandatory):

iss: JWT issuer

sub: targeted users (JWT targeted users)

aud: receiving JWT party

exp: expiration time stamp (JWT’s expiration time, which must be greater than the issuing time)

nbf: defines when the JWT is unavailable

iat: JWT’s issuing time

jti: JWT’s unique ID, mainly used as a one-time IDtokenTo avoid replay attacks.

Public statement:

Any information can be added to the public declaration. Generally, the user’s relevant information or other necessary information required by the business can be added. However, it is not recommended to add sensitive information because this part can be decrypted at the client

Private declaration:

Private declaration is a declaration jointly defined by providers and consumers. It is generally not recommended to store sensitive information becausebase64Symmetric decryption means that this part of the information can be classified as plaintext information.

Signature

The third part of JWT is a visa information, which consists of three parts:

Header (after Base64)

Payload (after Base64)


secret


This part needsbase64Encryptedheaderandbase64Encryptedpayloaduse.A string composed of connections, and then throughheaderAdd salt according to the encryption method stated insecretCombined encryption, and thenjwtThe third part.

secret keysecretIt is saved in the server, and the server will generate it according to this keytokenAnd verification, so it needs to be protected.

Let’s integrate springboot and JWT

introduceJWTDependency, because it is based onJava, so what you need isjava-jwt

<dependency>
      <groupId>com.auth0</groupId>
      <artifactId>java-jwt</artifactId>
      <version>3.4.0</version>
</dependency>

You need to customize an annotation

Annotations that need to be logged in and have roles to operateLoginRequired

@Target({ElementType.METHOD, ElementType.TYPE})
@TargetPurpose of annotation:

@Target(ElementType.TYPE)——Interface, class, enumeration, annotation

@Target(ElementType.FIELD)——Field, enumerated constant

@Target(ElementType.METHOD)——Method

@Target(ElementType.PARAMETER)——Method parameters

@Target(ElementType.CONSTRUCTOR)——Constructor

@Target(ElementType.LOCAL_VARIABLE)——Local variable

@Target(ElementType.ANNOTATION_TYPE)——Annotation

@Target(ElementType.PACKAGE)——Package

@Retention: reserved position of annotation

RetentionPolicy.SOURCE: this type ofAnnotationsIt is reserved only at the source code level and will be ignored at compile timeclassThe bytecode file does not contain.

RetentionPolicy.CLASS: this type ofAnnotationsIt is reserved at compile time. The default retention policy isclassFile exists, butJVMWill be ignored and not available at runtime.

RetentionPolicy.RUNTIME: this type ofAnnotationsWill beJVMReserved, so they can be used at run timeJVMOr other code that uses reflection mechanisms.


@DocumentNote: this annotation will be included injavadocin

@Inherited: the subclass can inherit the annotation in the parent class

Simply customize an entity classUser, uselombokSimplify the writing of entity classes

@Data


@Accessors(chain = true)


public class AuthUserVO extends BaseVO {

/**

}

Need to writetokenGeneration method of

/**

Algorithm.HMAC256(): useHS256generatetokenThe key is the user’s password, and the unique key can be saved on the server.

withAudience()Deposit needs to be saved intokenHere I put the user’s informationIDDeposittokenin

Next, you need to write an interceptor to get ittokenAnd verifytoken

To implement an interceptor, you need to implementHandlerInterceptorInterface

HandlerInterceptorThe interface mainly defines three methods

1.boolean preHandle ()

The preprocessing callback method realizes the preprocessing of the processor. The third parameter is the response processor, which is customizedController, the return value istrueIndicates to continue the process (such as calling the next interceptor or processor) or to execute next

postHandle()andafterCompletion()falseIndicates that the process is interrupted and will not continue to call other interceptors or processors to interrupt execution.

2.void postHandle()

The post-processing callback method realizes the post-processing of the processor(DispatcherServletThe view is returned (called before rendering), and we can use themodelAndView(model and view objects) processing model data or views,modelAndViewIt may also benull

3.void afterCompletion():

The callback method after the entire request is processed, which also needs the current corresponding methodInterceptorofpreHandle()Only when the return value of is true, that isDispatcherServletExecute after rendering the corresponding view. Used for resource cleanup. Callback method after the entire request is processed. For example, in performance monitoring, we can record the end time and output the consumption time here, and clean up some resources, similar totry-catch-finallyMediumfinally, but only calls the processor in the execution chain

Main process:

1. FromhttpRequest headertoken

2. Determine whether to map to method

3. Check whether there ispasstokenNote, skip authentication if any

4. Check whether there are any notes requiring user login. If yes, take them out and verify them

5. If you pass the authentication, you can access it. If you fail, you will report relevant error information

Configuring Interceptors

Added annotation on configuration class@ConfigurationIndicates that this class is a configuration class and will be used as aSpringBeanAdd toIOCIn container

@Configuration

WebMvcConfigurerAdapterIn fact, there is no method implementation in this abstract class, but the interface is empty

WebMvcConfigurerAll the methods in the system do not give any business logic processing. This design is just right so that we don’t have to implement those methods we don’t use. It’s up to usWebMvcConfigurerAdapterAbstract class empty implementation, if we need to make logical processing for a specific method, we only need to

WebMvcConfigurerAdapterIn subclass@OverrideThe corresponding method is OK.

Note:

staySpringBoot2.0andSpring 5.0inWebMvcConfigurerAdapterAbandoned

It is said on the Internet to inheritWebMvcConfigurationSupport, but after a try, it’s still overdue

resolvent:

Direct implementationWebMvcConfigurer(official recommendation)

@Override

InterceptorRegistryInternaladdInterceptorAn implementation is requiredHandlerInterceptorInterceptor instance of the interface,addPathPatternsMethod is used to set the filter path rule of the interceptor.

Here I intercept all requests by judging whether there are any@LoginRequiredAnnotations determine whether login is required

Add the login operation annotation in the data access interface

@LoginRequired
    @PutMapping("/admin/v1/update")
    public Result updateUser(@RequestBody AuthUserVO authUserVO) {
        return authUserService.updateUser(authUserVO);
    }

Logout login

Many online cases rarely talk about how to log out. Some people say that it is better to directly generate a new token. I think the back-end control is better. Here, I store every generated token and use a timer to scan the expired tokens here. Every time I check, I go to the database to see if there is any. If there is no token, it will be reported that the token verification fails.

/**

timer

@Override
    public Result logout() {
        UserSessionVO userSessionInfo = SessionUtil.getUserSessionInfo();
        this.authTokenDao.delete(new LambdaQueryWrapper<AuthToken>().eq(AuthToken::getUserId, userSessionInfo.getId()));
        return Result.createWithSuccessMessage();
    }

timer

@Scheduled(cron = "0 0/1 * * * ?")

If it is not annotated, it is not verified by default. Generally, the login interface is not verified. staygetMessage()I added the login annotation in, indicating that the interface must be logged in and obtainedtokenAfter, add in the request headertokenAnd can only be accessed after verification

Note: herekeyIt must not be wrong, because the keyword is taken in the interceptortokenValue of

String token = httpServletRequest.getHeader(Constants.AUTHENTICATION);

addtokenAfter that, you can successfully pass the verification and interface access

GitHub project source address:https://github.com/byteblogs168/hello-blog

This is my recent open-source Hello blog. Welcome to star

Note: This article refers tohttps://www.jianshu.com/p/e88d3f8151db

This work adoptsCC agreement, reprint must indicate the author and the link to this article