Spring boot learning note 21 -- JWT implementation of login verification

Today, let's record how to use JWT to implement user login verification.

The effect of the implementation is that a token will be returned to the client for subsequent login verification. After login, the client needs to put the token in the requested head, otherwise the returned login fails. Don't talk much and go straight to the code.

1.JWT tools

There is a simple example of JWT in the previous article. Later, I improved it. The code is as follows:

package com.youyou.shiro.jwt;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.youyou.util.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.Date;

/**
 * @author youyou
 * <br/>date 2019-01-09
 */
public class JwtUtil {

    private static final String USERNAME = "username";

    private static final String KEY = "123456qwe";

    /**
     * Expiration time (minutes)
     */
    private static final int EXPIRATION_TIME = 5;

    /**
     * Generate token
     *
     * @param userName
     * @return
     * @author Liu Peng
     * <br/>date 2019-01-09
     */
    public static String createToken(String userName) {
        Algorithm algorithm = Algorithm.HMAC256(KEY);

        Date expirationDate = DateUtil.addMinutes(DateUtil.getNow(), EXPIRATION_TIME);
        //Generate token
        return JWT.create().withClaim(USERNAME, userName)
                .withExpiresAt(expirationDate)
                .sign(algorithm);
    }

    /**
     * Get user name
     *
     * @param token
     * @return
     * @author Liu Peng
     * <br/>date 2019-03-08
     */
    public static String getUsername(String token) {
        return getValueByToken(token, USERNAME);
    }

    /**
     * Get value in token
     *
     * @param token
     * @param key
     * @return
     */
    public static String getValueByToken(String token, String key) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(KEY)).build();
        DecodedJWT decode = verifier.verify(token);
        return decode.getClaim(key).asString();
    }

    /**
     * Verify whether it is expired, and return true after expiration
     * @param token
     * @return
     * @author Liu Peng
     * <br/>date 2019-03-12
     */
    public static boolean isExpires(String token){
        if(StringUtils.isBlank(token)){
            return true;
        }
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(KEY)).build();
        try {
            verifier.verify(token);
        }catch (JWTVerificationException e){
            return true;
        }
        return false;
    }

   

}

2. Log in to Controller

The blogger here uses mybatis plus to build orm framework. If you are interested, you can see the previous post https://blog.csdn.net/lp840312696/article/details/83691915

package com.youyou.login.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.youyou.common.http.ResponseMessage;
import com.youyou.common.http.Result;
import com.youyou.login.entity.UserDO;
import com.youyou.login.service.LoginService;
import com.youyou.shiro.jwt.JwtUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

/**
 * Logon interface
 *
 * @author Liu Peng
 * <br/>date 2019-03-12
 */
@Api(description = "Logon interface")
@RestController
@RequestMapping("/login")
public class LoginController {

    @Autowired
    private LoginService service;


    @ApiOperation(value = "Sign in")
    @PostMapping("")
    public ResponseMessage<String> login(String username, String password) {

        if(StringUtils.isAnyBlank(username , password)){
            return Result.error("User name and password cannot be empty!");
        }

        QueryWrapper<UserDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name" ,username);
        queryWrapper.eq("password" ,password);

        UserDO userDO = service.querySingle(queryWrapper);
        if(Objects.isNull(userDO)){
            return Result.error("Wrong user name and password!");
        }

        //Generate a token
        String token = JwtUtil.createToken(username);



        return Result.success(token);
    }

}

3. Create filter

package com.youyou.login.config;

import com.youyou.login.filter.LoginFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Login interception configuration
 *
 * @author Liu Peng
 * <br/>date 2019-03-21
 */

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean loginFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new LoginFilter());
        registration.addUrlPatterns("/api/*");
        registration.setName("LoginFilter");
        //The smaller the number, the earlier the execution
        registration.setOrder(6);
        return registration;
    }

}

After three steps of configuration, the login verification has been completed. The interface that can only be accessed after login needs to start with api.

4. Configure swagger (this step is not important. If swagger is not used, it can be ignored)

If you use swagger, you will have this problem. When you use swagger for testing, you also need to pass token for login verification, so you need the following configuration

package com.youyou.config;

import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket swaggerSpringMvcPlugin() {

        return initDocket();
        //Simple configuration of swagger
//        return new Docket(DocumentationType.SWAGGER_2).select()
//                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).build();
    }

    /**
     * Add an Authorization parameter entry box to each interface in the swagger interface to verify the login
     * @param
     * @return
     * @author Liu Peng
     * <br/>date 2019-03-25
     */
    public static Docket initDocket() {
        ParameterBuilder parameterBuilder = new ParameterBuilder();
        List<Parameter> parameters = new ArrayList<>();
        parameterBuilder.name("Authorization").description("token").modelRef(new ModelRef("string"))
                .parameterType("header").required(false).build();
        parameters.add(parameterBuilder.build());

        return new Docket(DocumentationType.SWAGGER_2).select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).build()
                .globalOperationParameters(parameters);
    }

}

It's over here. Welcome to leave a message for discussion!

 

 

 

 

Keywords: Java Shiro Apache Mybatis

Added by SZero on Mon, 02 Dec 2019 08:23:26 +0200