springboot + jwt landing permission to implement token authentication

I. Introduction

The contents of this article is to learn shortly, and finally to the weekend time code article sharing knowledge seekers fans who, after studying this article, the reader will be landing certification process token classes have a comprehensive understanding, can dynamically build own login authentication process; for small projects it is a lightweight authentication mechanism, in line with development needs; more attention Princess exciting original content knowledge seekers, the reader is certain, is the greatest support for the author's creative ;

Two landing jwt achieve certification process

  • User accounts and post requests issued surface
  • The server uses the private key after receiving the request to create a jwt, here will generate a token
  • The server returns to the browser jwt
  • jwt browser needs to be placed with a token request header
  • Each hand to client requests, the server authentication token is jwt
  • Verify successful return of resources in response to the browser. Otherwise, exception handling

Three related presentations jwt

3.1jwt composition

JWT token of the three pieces of information composed of these three pieces of information with the text .connected together constitute JWT string;

  • Header header (which contains meta data token, and contains the type of a signature or an encryption algorithm and a)
  • Payload load
  • Signature Signature / visa
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg

3.2 jwt advantage

  • Simple (Compact): can URL, POSTparameters or HTTP headertransmission, a small amount of data, transmission speed
  • Self-contained (Self-contained): load contains all the information needed by the user, to avoid multiple database queries
  • Because Tokenis JSONencrypted form stored in the client, so JWTthat cross-language support;
  • No need to store session information in the server for distributed micro and services;

User login token issued four jwt

4.1 pom.xml

Project members are as follows

  • springboot 2.1;
  • jwt 3.4.0;
  • maven 3.5
  • jdk1.8
  • postman interface test
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

4.2jwt Tools

jwt tool class has three methods, namely, generating a digital signature for transmitting to the client when the user jwt first landing; followed by verification method for interceptors intercepting url in all rules, each request with a server must jwt transmitted, verified after release request; last method of a user name for the query key, the verification jwt as a parameter;

/* *
 * @Author lsc
 * <p> JWT工具类 </p>
 * @Param
 * @Return
 */
public class JwtUtil {

	// Token过期时间30分钟
	public static final long EXPIRE_TIME = 30 * 60 * 1000;

	/* *
	 * @Author lsc
	 * <p> 校验token是否正确 </p>
	 * @Param token
	 * @Param username
	 * @Param secret
	 * @Return boolean
	 */
	public static boolean verify(String token, String username, String secret) {
		try {
			// 设置加密算法
			Algorithm algorithm = Algorithm.HMAC256(secret);
			JWTVerifier verifier = JWT.require(algorithm)
					.withClaim("username", username)
					.build();
			// 效验TOKEN
			DecodedJWT jwt = verifier.verify(token);
			return true;
		} catch (Exception exception) {
			return false;
		}
	}



	/* *
	 * @Author lsc
	 * <p>生成签名,30min后过期 </p>
	 * @Param [username, secret]
	 * @Return java.lang.String
	 */
	public static String sign(String username, String secret) {
		Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
		Algorithm algorithm = Algorithm.HMAC256(secret);
		// 附带username信息
		return JWT.create()
				.withClaim("username", username)
				.withExpiresAt(date)
				.sign(algorithm);

	}

	/* *
	 * @Author lsc
	 * <p> 获得用户名 </p>
	 * @Param [request]
	 * @Return java.lang.String
	 */
	public static String getUserNameByToken(HttpServletRequest request)  {
		String token = request.getHeader("token");
		DecodedJWT jwt = JWT.decode(token);
		return jwt.getClaim("username")
				.asString();
	}



}

4.3 user entity

Entity contains the user name and password, keep things simple;


/**
 * @Author lsc
 * <p> </p>
 */
@Data
public class SysUser {

    private String username;

    private String password;

}

4.4Controller

Presentation code User login authentication, issued after successful authentication token to the client;

/**
 * @Author lsc
 * <p> </p>
 */
@RestController
public class SysUserController {

    @PostMapping(value = "/login")
    public Map<String, Object> login(@RequestBody SysUser sysUser){
        Map<String, Object> map = new HashMap<>();
        String username = sysUser.getUsername();
        String password = sysUser.getPassword();
        // 省略 账号密码验证
        // 验证成功后发送token
        String token = JwtUtil.sign(username,password);
        if (token != null){
            map.put("code", "200");
            map.put("message","认证成功");
            map.put("token", token);
            return map;
        }
        map.put("code", "403");
        map.put("message","认证失败");
        return map;
    }
}

4.5 Test

Test url http: // localhost: 8080 / login

Test parameters were as follows postman post request

{
	"username": "zszxz",
	"password": "zszxz"
}

Return follows

{
    "code": "200",
    "message": "认证成功",
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1ODI4OTc4NDUsInVzZXJuYW1lIjoienN6eHoifQ.vyiExkFWCCmQA3PFYL0jJfIiYGWubngqB0WcgmtHOxg"
}

Five jwt landing interception certification

After payment has already been achieved jwt based login authentication token to the client; this section is the token into the request header to send a request to the server; server to use interceptors to intercept a request for a token to authenticate; validate the request by the success, or failure to request resources ;

5.1 custom interceptor

Custom interceptor JwtInterceptor, HandlerInterceptor implement the interface, each time prior to reaching the authentication request token is valid;

/**
 * @Author lsc
 * <p>token验证拦截器 </p>
 */
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    SysUserService sysUserService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 从 http 请求头中取出 token
        String token = request.getHeader("token");
        // 如果不是映射到方法直接通过
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        if (token != null){
            String username = JwtUtil.getUserNameByToken(request);
            // 这边拿到的 用户名 应该去数据库查询获得密码,简略,步骤在service直接获取密码
            boolean result = JwtUtil.verify(token,username,sysUserService.getPassword());
            if(result){
                System.out.println("通过拦截器");
                return true;
            }
        }
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

5.2 service

/**
 * @Author lsc
 * <p> 模拟查询数据库获得账号密码 </p>
 */
@Service
public class SysUserService {


    public String getPassword(){
        return "zszxz";
    }
}

5.3 interceptor configuration

Interceptor intercepts the request configuration rules defined in the main, the injection interceptor WebMvcConfigurer; cors cross-domain processing;

/* *
 * @Author lsc
 * <p>拦截器配置 </p>
 * @Param
 * @Return
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    /* *
     * @Author lsc
     * <p> 设置拦截路径 </p>
     * @Param [registry]
     * @Return void
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/login");
    }
    /* *
     * @Author lsc
     * <p> 将拦截器注入context </p>
     * @Param []
     * @Return com.zszxz.jwt.interceptor.JwtInterceptor
     */
    @Bean
    public JwtInterceptor authenticationInterceptor() {
        return new JwtInterceptor();
    }

    /* *
     * @Author lsc
     * <p>跨域支持 </p>
     * @Param [registry]
     * @Return void
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")
                .maxAge(3600 * 24);
    }
}

5.4Controller

Presentation layer interface is used to intercept the pro-demand test

/**
 * @Author lsc
 * <p> </p>
 */
@RestController
public class TestController {

    @GetMapping(value = "/api/test")
    public String get(){

        return "zszxz";
    }
}

5.5 Test

Test url http: // localhost: 8080 / api / test

Send get request to the server, with a request header, key token is, for the first time the user returns the value of the token landing string;

Test returns as follows

zszxz

Six official website link

https://jwt.io/introduction/

Source of concern Princess or column description can be obtained;

Published 125 original articles · won praise 337 · Views 150,000 +

Guess you like

Origin blog.csdn.net/youku1327/article/details/104564953