Spring集成JWT

1.现在的项目,大多数是前后端分离的项目,这样就产生了一个前端跨域的问题,而JWT就能帮助开发者解决前后端的跨域问题,前端请求拿到令牌,把令牌放到请求头,后端设置过滤器或者拦截器,拦截签名,并且验证,通过之后就放行,这大大提高了系统的安全性。

2.token主要包含三部分:头部+负载+签名

3.下面是我写的简单JWT集成,方便初学者进行理解。

4.添加项目所需要的依赖:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.6.4
         
    
    com.example
    jwtdemo
    0.0.1-SNAPSHOT
    jwtdemo
    jwtdemo
    
        1.8
    
    
        
            org.springframework.boot
            spring-boot-starter
        
        
            com.auth0
            java-jwt
            3.10.3
        

        
            org.projectlombok
            lombok
        

        
            com.alibaba
            fastjson
            1.2.30
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            org.springframework.boot
            spring-boot-starter-web
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        paketobuildpacks/builder-jammy-base:latest
                    
                
            
        
    


5.配置文件

server:
  port: 8085




#生成token需要的参数
com:
  example:
    type: JWT
    alg: HS256
    secret: dsij787eawGa7wa!dsadlwdasd
    expireTime: 6000000


6.创建配置类,获取配置信息。

package com.example.jwtdemo.config;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

/**
 * @className:@JWTConfig
 * @Description:TODO
 * @Author:
 * @Version:1.0
 **/
@Configuration
@Data
public class JWTConfig {
    @Value("${com.example.type}")
    private String type;
    @Value("${com.example.alg}")
    private String alg;
    @Value("${com.example.secret}")
    private String secret;
    @Value("${com.example.expireTime}")
    private Integer expireTime;
}

7.创建签名组件类

package com.example.jwtdemo.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.jwtdemo.config.JWTConfig;
import com.example.jwtdemo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @className:@TokenUtil
 * @Description: Token主要有三部分组成 头部+负载+签名
 * @Author:
 * @Version:1.0
 **/
@Component
public class TokenUtil {

    @Autowired
    private JWTConfig jwtConfig;
    public String createToken(User user){

        Map headers = new HashMap<>();
        headers.put("type",jwtConfig.getType());
        headers.put("alg",jwtConfig.getAlg());

        Algorithm algorithm = Algorithm.HMAC256(jwtConfig.getSecret());

        //设置过期时间
        Date expireDate =  new Date(System.currentTimeMillis()+jwtConfig.getExpireTime());
        String token = JWT.create()
                .withClaim("id",user.getId())
                .withClaim("username",user.getUsername())
                .withClaim("roleId",user.getRoleId())
                 .withIssuer("admin")
                .withNotBefore(new Date())
                .withExpiresAt(expireDate)
                .sign(algorithm);



        return  token;
    }






}

8.创建controller进行测试

package com.example.jwtdemo.controller;

import com.alibaba.fastjson.JSONObject;
import com.example.jwtdemo.model.User;
import com.example.jwtdemo.util.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @className:@LoginConroller
 * @Description:TODO
 * @Author:
 * @Version:1.0
 **/
@RestController
@RequestMapping("/")
public class LoginConroller {


    @Autowired
    private TokenUtil tokenUtil;

    @PostMapping("/login")
    public String login(@RequestBody @Validated JSONObject jsonObject){

        String username = jsonObject.getString("username");
        String password = jsonObject.getString("password");
        User u = new User();
        if (password.equals("admin")){
            u.setRoleId(1);
            u.setId(1);
            u.setUsername("username11");
            return tokenUtil.createToken(u);

        }else {
            return "error";
        }

    }

    @GetMapping("/getUser")
    public String getUser(Integer id){
        return "success";
    }

}

9.创建过滤器

package com.example.jwtdemo.filter;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.jwtdemo.config.JWTConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * @className:@JWTFilter
 * @Description:TODO
 * @Author:
 * @Version:1.0
 **/
@Component
@WebFilter(filterName = "jwtFilter",urlPatterns = {"/*"})
public class JWTFilter  implements Filter {

    private Logger logger = LoggerFactory.getLogger(JWTFilter.class);

    @Autowired
    private JWTConfig config;

    //登录拦截
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) servletRequest;
        String url = req.getRequestURL().toString();
        //指定放开路径
        String urls [] ={"/login","/xxx"};
        logger.info("url====={}",url);
        //是否放行
        boolean isFilter = false;
        for (String u:urls){
            if (url.contains(u)){
                isFilter =true;
            }
        }
        //拦截认证
        if (!isFilter){
            //获取token的值
            try {
                PrintWriter printWriter  =servletResponse.getWriter();
                String token = req.getHeader("token");
                if (StringUtils.isEmpty(token)){
                    throw new Exception("token不为空");
                }
                Algorithm algorithm = Algorithm.HMAC256(config.getSecret());
                //验证签名是否正确
                DecodedJWT decodedJWT = JWT.require(algorithm).build().verify(token);
                //获取jwt中的业务信息
                Integer id = decodedJWT.getClaim("id").asInt();
                String username = decodedJWT.getClaim("username").asString();
                Integer roleId = decodedJWT.getClaim("roleId").asInt();

            }catch (Exception e){
                //logger.info("签名验证失败,token不正确{}",e.getMessage());
                PrintWriter writer = null;
                servletResponse.setCharacterEncoding("UTF-8");
                servletResponse.setContentType("text/html; charset=utf-8");
                MapresMap = new HashMap<>();
                resMap.put("code",500);
                resMap.put("msg","签名失败!");
                resMap.put("data",null);
                writer = servletResponse.getWriter();
                writer.print(resMap);
                return ;

            }

        }
        filterChain.doFilter(servletRequest,servletResponse);

    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }
}

9.总结:名词解释

过滤器:过滤请求路径,除了指定不拦截的路径,其他路径均要拦截,拦截之后,对token进行验签,通过之后,才可访问后端相应路径。

token:token是一个将用户信息合成然后进行签名的一串字符,验签就是类似一个解密的过程,能获取到用户具体的信息。

你可能感兴趣的:(Spring集成JWT)