SpringBoot learning - 4 integrated JWT

1, Json web token (JWT) is a statement in order to pass between the network application execution environment JSON-based development standards (RFC 7519), the token is designed to be compact and safe, especially for a single point of distributed sites login (SSO) scenarios. JWT's statement is generally used between identity providers and service providers to deliver the authenticated user identity information in order to obtain resources from the server, you can also add some additional business logic other necessary information statement, the token also may be directly used for authentication may be encrypted.

2, pom.xml add the following code to add dependencies JWT

<!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.9.0</version>
</dependency>

3, IDEA2019.3 Chinese distortion version, provided UTF-8 does not work, the following modifications Font

 

以下几部分内容主要参考
https://www.cnblogs.com/30go/p/10963924.html
https://www.jianshu.com/p/9af8612f6aef

 4、在Utils文件夹下增加TokenUtil

RefreshToken暂不使用

package com.jgui.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import com.jgui.domain.JUser;

import java.util.Date;

/**
 * @Author: zhaogaojian
 * @Description:
 * @Date: Created in 2020/1/722:13
 */
public class TokenUtil {
    private static final long TOKEN_EXPIRE_TIME= 30*60*1000;//超时时间30分钟
    private static final long REFRESH_TOKEN_EXPIRE_TIME= 15*24*60*1000;//超时时间15天
    private static final String TOKEN_SECRET="jguiafadfiierpewirpew8908ewrq";//秘钥
    private static final String ISSUER="jgadmin";//签发人
    /**
     * 签名生成
     * @param user
     * @return
     */
    public static String sign(JUser user){

        String token = "";
        try {
            Date expiresAt = new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME);
            Date now = new Date();
            token = JWT.create()
                    .withIssuer(ISSUER)
                    .withClaim("username", user.getUsername())
                    .withExpiresAt(expiresAt)
                    .withIssuedAt(now)
                    // 使用了HMAC256加密算法。
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (Exception e){
            e.printStackTrace();
        }
        return token;

    }
    /**
     * 签名验证
     * @param token
     * @return
     */
    public static boolean verify(String token){
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT jwt = verifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("issuer: " + jwt.getIssuer());
            System.out.println("username: " + jwt.getClaim("username").asString());
            System.out.println("签发时间:" + jwt.getIssuedAt());
            System.out.println("过期时间:" + jwt.getExpiresAt());
            return true;
        } catch (Exception e){
            return false;
        }

    }
    /**
     * 从token获取username
     */
    public static String getUsername(String token){
        try{
            return JWT.decode(token).getClaim("username").asString();
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return "";
    }
}
package com.jgui.utils;

import java.util.UUID;

/**
 * @Author: zhaogaojian
 * @Description:
 * @Date: Created in 2020/1/722:50
 */
public class StringUtil {
    public static String GetUUIDString()
    {
       return UUID.randomUUID().toString();
    }

}

5、在Controller下增加LoginController

package com.jgui.controller;

import com.jgui.dao.JUserDao;
import com.jgui.domain.JUser;
import com.jgui.utils.StringUtil;
import com.jgui.utils.TokenUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zhaogaojian
 * @Description:
 * @Date: Created in 2020/1/722:38
 */
@RestController
public class LoginController {
    @Resource
    private JUserDao userDao;
    @GetMapping("/login")
    public Map<String,Object> login(@RequestParam String username, @RequestParam String password) {

        if("zhangsan".equals(username) && "123".equals(password)){
            JUser user=new JUser();
            user.setUsername("zhangsan");
            user.setRealname("张三");
            Map<String,Object> map = new HashMap<>();
            //生成token
            String token = TokenUtil.sign(user);
            String refreshToken = StringUtil.GetUUIDString();
            if(token != ""){
                map.put("code", "10000");
                map.put("message", "认证成功");
                map.put("token", token);
                map.put("refreshtoken", refreshToken);
                return map;
            }
        }
        Map<String,Object> map = new HashMap<>();
        map.put("code", "10001");
        map.put("message", "认证失败");
        map.put("token", "");
        map.put("refreshtoken", "");
        return map;
    }
}

6、在Interceptor目录下增加TokenInterceptor

package com.jgui.interceptor;
import com.jgui.utils.TokenUtil;
import net.minidev.json.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
/**
 * @Author: zhaogaojian
 * @Description:
 * @Date: Created in 2020/1/723:12
 */
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{

        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        response.setCharacterEncoding("utf-8");
        String token = request.getHeader("token");
        if(token != null){
            boolean result = TokenUtil.verify(token);
            if(result){
                System.out.println("通过拦截器");
                return true;
            }
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try{
            JSONObject json = new JSONObject();
            json.put("success","false");
            json.put("msg","认证失败,未通过拦截器");
            json.put("code","10003");
            response.getWriter().append(json.toJSONString());
            System.out.println("认证失败,未通过拦截器");
        }catch (Exception e){
            e.printStackTrace();
            response.sendError(500);
            return false;
        }
        return false;

    }

}

7、在config下增加InterceptorConfig

package com.jgui.config;

/**
 * @Author: zhaogaojian
 * @Description:
 * @Date: Created in 2020/1/723:15
 */
import com.jgui.interceptor.TokenInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
 * 拦截器配置
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    private TokenInterceptor tokenInterceptor;
    //构造方法
    public InterceptorConfig(TokenInterceptor tokenInterceptor){
        this.tokenInterceptor = tokenInterceptor;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        List<String> excludePath = new ArrayList<>();
        excludePath.add("/user_register"); //注册
        excludePath.add("/login"); //登录
        excludePath.add("/logout"); //登出
        excludePath.add("/static/**");  //静态资源
        excludePath.add("/assets/**");  //静态资源

        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(excludePath);
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

8、运行项目

可以发现之前的http://localhost:8080/Hello

访问时会因为拦截器而导致无法访问

login接口因为被排除在拦截器外可以访问

 

 

 

 以上内容主要参考
https://www.cnblogs.com/30go/p/10963924.html
https://www.jianshu.com/p/9af8612f6aef

下一节将增加Redis及数据库验证

Guess you like

Origin www.cnblogs.com/zhaogaojian/p/12164349.html