Springboot 2.X 简单集成 JWT

代码地址 https://github.com/kingxiao6317/jwtDemo

一 、依赖

<!-- jwt -->
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt</artifactId>
   <version>0.9.0</version>
</dependency>

二、工具

开发工具:idea

jdk:1.8

系统:win10

三、搭建环境

1. 首先搭建springboot项目, 具体可以参考我的另外一篇文章

   idea创建Springboot 2.X项目

2. pom中添加JWT依赖,等待下载依赖包

<dependency>
   <groupId>joda-time</groupId>
   <artifactId>joda-time</artifactId>
   <version>2.10.3</version>
</dependency>
<dependency>
  <groupId>org.apache.commons</groupId>
   <artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>
<!-- jwt -->
 <dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

3. 创建JWT中保存数据的类 JwtInfo

可以不用实体直接使用字段传递数据,用实体的话后期扩展比较简单,比如:现在JWT中值保存了用户Id,后期想加入用户名,就可以直接在实体中添加字段,修改对应的代码就行了


import lombok.Data;

import java.io.Serializable;

/**
 * JWT中保存的信息
 * @author: clx
 * @date: 2019/7/22
 * @version: 1.1.0
 */
@Data
public class JWTInfo implements Serializable {
    /**
     * 用户Id
     */
    private String userId;
    /**
     * 用户名字
     */
    private String userName;

    public JWTInfo(String userId, String userName) {
        this.userId = userId;
        this.userName = userName;
    }
}

4. 创建JWT核心处理类


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;

/**
 * JWT加密解析
 * @author: clx
 * @date: 2019/7/22
 * @version: 1.1.0
 */
@Component
public class JWTHelper {

	public static String JWT_SECRET = "JWT_SECRET";
	
    /**
     * 密钥加密token 获取token
     *
     * @param jwtInfo jwt要加密的信息
     * @param expire 过期时间 单位/秒
     * @return
     * @throws Exception
     */
    public static String generateToken(JWTInfo jwtInfo, int expire) throws Exception {
        String compactJws = Jwts.builder()
                .setSubject(jwtInfo.getUserName())
                .claim("userId", jwtInfo.getUserId())
                .claim("userName", jwtInfo.getUserName())
                // 默认7天时间过期
                .setExpiration(DateTime.now().plusSeconds((expire == 0 ? 7 : expire)*3600*24).toDate())
                // 1天时间过期
//                .setExpiration(DateTime.now().plusSeconds(3600*24).toDate())
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET.getBytes())
                .compact();
        return compactJws;
    }
    
    /**
     * 解析验证token
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static Jws<Claims> parserToken(String token) throws Exception {
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(JWT_SECRET.getBytes()).parseClaimsJws(token);
        return claimsJws;
    }

    /**
     * 获取token中的用户信息
     *
     * @param token
     * @return
     * @throws Exception
     */
    public static JWTInfo getInfoFromToken(String token) throws Exception {
        Jws<Claims> claimsJws = parserToken(token);
        Claims body = claimsJws.getBody();
        return new JWTInfo(getObjectValue(body.get("userId")), getObjectValue(body.get("userName")));
    }


    private static String getObjectValue(Object obj){
        return obj==null?"":obj.toString();
    }

}

5. 创建拦截器


import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 拦截器获取token并验证token
 * @author: clx
 * @date: 2019/7/22
 * @version: 1.1.0
 */
public class JWTInterceptor implements HandlerInterceptor {


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
        // 如果不是映射到方法直接通过
        if(!(object instanceof HandlerMethod)){
            return true;
        }

        // 从 http 请求头中取出 token
        String token = request.getHeader("Authorization");
        System.out.println(request.getRequestURI());
        if (StringUtils.isBlank(token)) {
            throw new RuntimeException("无token,请重新登录");
        }
        // 校验token
        JWTHelper.parserToken(token);

        return true;

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest,
                           HttpServletResponse httpServletResponse,
                           Object o, ModelAndView modelAndView) throws Exception {

    }
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest,
                                HttpServletResponse httpServletResponse,
                                Object o, Exception e) throws Exception {
    }
}

6. 注册拦截器

注意: 要把测试controller中的 获取token和不需要token就能调用的接口先过滤掉


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


/**
 * 拦截器注册
 * @author: clx
 * @date: 2019/5/27
 * @version: 1.1.0
 */
@Configuration
public class JWTConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**")
                // 过滤不来拦截的请求路径, 可以写在配置文件中读取
        .excludePathPatterns("/jwtTest/unToken","/jwtTest/getToken");

    }
    @Bean
    public JWTInterceptor authenticationInterceptor() {
        return new JWTInterceptor();
    }
}

7. 创建测试


import com.example.jwtdemo.jwt.JWTHelper;
import com.example.jwtdemo.jwt.JWTInfo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * jwt测试类
 * @author: clx
 * @date: 2019/7/22
 * @version: 1.1.0
 */
@RestController
@RequestMapping("/jwtTest")
public class JWTTestController {

    /**
     * 获得token
     * @param userId
     * @param userName
     * @return
     * @throws Exception
     */
    @GetMapping("/getToken")
    public Object getToken(String userId, String userName) throws Exception {
        return JWTHelper.generateToken(new JWTInfo(userId, userName), 0);
    }

    /**
     * 不需要验证的接口
     * @return
     */
    @GetMapping("/unToken")
    public String unToken() {
        return "不需要验证token,接口调用成功";
    }

    /**
     * 需要验证的接口
     * @return
     */
    @GetMapping("/needToken")
    public String needToken() {
        return "token验证正常,接口调用成功";
    }
}

8.  启动项目测试

8.1 获取token

获取token成功

8.2 调用不需要token的接口

调用成功

8.2 调用需要token验证的接口

1)先不添加token调用

无法访问接口,提示错误信息

2) 带上8,1返回的token进行访问

调用成功,返回对应数据

9. 成功

 

代码地址 https://github.com/kingxiao6317/jwtDemo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值