上一篇文章《一分钟带你了解JWT认证!》介绍了JWT的组成和认证原理,本文将介绍下SpringBoot整合JWT实现认证的过程,带你更深入的了解下JWT。

一、JWT认证流程

认证流程如下:

  1. 用户使用账号和密码发出post请求;
  2. 服务器使用私钥创建一个jwt;
  3. 服务器返回这个jwt给浏览器;
  4. 浏览器将该jwt串在请求头中像服务器发送请求;
  5. 服务器验证该jwt;
  6. 返回响应的资源给浏览器。

二、SpringBoot整合JWT

新建一个spring boot项目spring-boot-jwt,按照下面步骤操作。

1.pom.xml引入jar包

<!-- 引入jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.8.2</version>
</dependency>

2.新建Jwt工具类

Jwt工具类进行token的生成和认证,工具类代码如下:

/**
* @description: Jwt工具类,生成JWT和认证
* @author: Java碎碎念
*/
public class JwtUtil { private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);
/**
* 密钥
*/
private static final String SECRET = "my_secret"; /**
* 过期时间
**/
private static final long EXPIRATION = 1800L;//单位为秒 /**
* 生成用户token,设置token超时时间
*/
public static String createToken(User user) {
//过期时间
Date expireDate = new Date(System.currentTimeMillis() + EXPIRATION * 1000);
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");
String token = JWT.create()
.withHeader(map)// 添加头部
//可以将基本信息放到claims中
.withClaim("id", user.getId())//userId
.withClaim("userName", user.getUserName())//userName
.withClaim("name", user.getName())//name
.withExpiresAt(expireDate) //超时设置,设置过期的日期
.withIssuedAt(new Date()) //签发时间
.sign(Algorithm.HMAC256(SECRET)); //SECRET加密
return token;
} /**
* 校验token并解析token
*/
public static Map<String, Claim> verifyToken(String token) {
DecodedJWT jwt = null;
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
jwt = verifier.verify(token);
} catch (Exception e) {
logger.error(e.getMessage());
logger.error("token解码异常");
//解码异常则抛出异常
return null;
}
return jwt.getClaims();
} }

3.添加JWT过滤器

JWT过滤器中进行token的校验和判断,,token不合法直接返回,合法则解密数据并把数据放到request中供后续使用。

为了使过滤器生效,需要在启动类添加注解@ServletComponentScan(basePackages = "com.example.springbootjwt.filter")。

JWT过滤器代码如下:

/**
* JWT过滤器,拦截 /secure的请求
*/
@Slf4j
@WebFilter(filterName = "JwtFilter", urlPatterns = "/secure/*")
public class JwtFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res; response.setCharacterEncoding("UTF-8");
//获取 header里的token
final String token = request.getHeader("authorization"); if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
chain.doFilter(request, response);
}
// Except OPTIONS, other request should be checked by JWT
else { if (token == null) {
response.getWriter().write("没有token!");
return;
} Map<String, Claim> userData = JwtUtil.verifyToken(token);
if (userData == null) {
response.getWriter().write("token不合法!");
return;
}
Integer id = userData.get("id").asInt();
String name = userData.get("name").asString();
String userName = userData.get("userName").asString();
//拦截器 拿到用户信息,放到request中
request.setAttribute("id", id);
request.setAttribute("name", name);
request.setAttribute("userName", userName);
chain.doFilter(req, res);
}
} @Override
public void destroy() {
}
}

4.添加登录Controller

登录Controller进行登录操作,登录成功后生产token并返回。

登录Controller代码如下:

/**
* 登录Controller
*/
@Slf4j
@RestController
public class LoginController { static Map<Integer, User> userMap = new HashMap<>(); static {
//模拟数据库
User user1 = new User(1, "zhangsan", "张三", "123456");
userMap.put(1, user1);
User user2 = new User(2, "lisi", "李四", "123123");
userMap.put(2, user2);
} /**
* 模拟用户 登录
*/
@RequestMapping("/login")
public String login(User user) {
for (User dbUser : userMap.values()) {
if (dbUser.getUserName().equals(user.getUserName()) && dbUser.getPassword().equals(user.getPassword())) {
log.info("登录成功!生成token!");
String token = JwtUtil.createToken(dbUser);
return token;
}
}
return "";
}
}

5.添加SecureController

SecureController中的请求会被JWT过滤器拦截,合法后才能访问。

SecureController代码如下:

/**
* 需要登录后才能访问
*/
@Slf4j
@RestController
public class SecureController { /**
* 查询 用户信息,登录后才能访问
*/
@RequestMapping("/secure/getUserInfo")
public String login(HttpServletRequest request) {
Integer id = (Integer) request.getAttribute("id");
String name = request.getAttribute("name").toString();
String userName = request.getAttribute("userName").toString();
return "当前用户信息id=" + id + ",name=" + name + ",userName=" + userName;
}
}

三、测试

测试分两步,首先访问登录接口,登录成功后获取token,然后拿着token在访问查询用户信息接口。

1.访问登录接口

打开PostMan,访问http://localhost:8080/login?userName=zhangsan&password=123456,登录成功后接口返回token,请求成功截图如下:

2.访问用户信息接口

打开PostMan,访问http://localhost:8080/secure/getUserInfo,header里需要携带token,请求成功截图如下:

到此SpringBoot整合JWT的功能已经全部实现,有问题欢迎留言沟通哦!

完整源码地址: https://github.com/suisui2019/springboot-study

推荐阅读

1.一分钟带你了解JWT认证!

2.SpringBoot中如何优雅的读取yml配置文件?

3.SpringBoot中如何灵活的实现接口数据的加解密功能?

4.SpringBoot中神奇的@Enable*注解?

5.Java中Integer.parseInt和Integer.valueOf,你还傻傻分不清吗?


限时领取免费Java相关资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并发分布式、大数据、机器学习等技术。

关注下方公众号即可免费领取:

SpringBoot集成JWT实现权限认证的更多相关文章

  1. springboot集成shiro实现权限认证

    github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...

  2. springboot之JWT实现权限认证

    1.在pom.xml添加依赖 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jw ...

  3. SpringBoot集成JWT 实现接口权限认证

    JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的, 特别适用于分布式站点 ...

  4. springboot使用jwt进行权限验证

    springboot使用jwt进行权限验证 依赖准备 首先导入对应的依赖 <dependencies> <dependency> <groupId>org.apac ...

  5. SpringBoot集成JWT实现token验证

    原文:https://www.jianshu.com/p/e88d3f8151db JWT官网: https://jwt.io/ JWT(Java版)的github地址:https://github. ...

  6. spring-boot整合shiro作权限认证

    spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro 废话不多说  引入pom文件 <!--shiro集成spring--& ...

  7. SpringBoot集成JWT

        JWT(json web tokens)是目前比较流行的跨域认证解决方案:说通俗点就是比较流行的token生成和校验的方案.碰巧公司有个app的项目的token采用了jwt方案,因此记录下后端 ...

  8. SpringBoot整合JWT实现登录认证

    什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...

  9. springboot集成shiro实现权限缓存和记住我

    到这节为止,我们已经实现了身份验证和权限验证.但是,如果我们登录之后多次访问http://localhost:8080/userInfo/userDel的话,会发现权限验证会每次都执行一次.这是有问题 ...

随机推荐

  1. uC/OS-III 时钟节拍(一)

    时钟节拍就是操作系统的时基,操作系统要实现时间上的管理,必须依赖于时基(时基即时间基准,操作系统的基准时钟). uC/OS-III时钟节拍的实现过程 时钟节拍就是系统以固定的频率产生中断(时基中断), ...

  2. Thinkphp5.0第五篇

    原样输出 使用literal标签防止模板标签被解析 例如 {literal} {$name}<br/> {/literal} 模板单行注释 {//注释内容} 多行注释 {/*注释内容*/} ...

  3. 【Elasticsearch 搜索之路】(一)什么是 Elasticsearch?

    本篇文章对 Elasticsearch 做了基本介绍,在后续将通过专栏的方式持续更新,本系列以 Elasticsearch7 作为主要的讲解版本,欢迎各位大佬指正,共同学习进步! 一般涉及大型数据库的 ...

  4. 我最推荐的一张Java后端学习路线图,Java工程师必备

    前言 学习路线图往往是学习一样技术的入门指南.网上搜到的Java学习路线图也是一抓一大把. 今天我只选一张图,仅此一图,足以包罗Java后端技术的知识点.所谓不求最好,但求最全,学习Java后端的同学 ...

  5. 推荐一款超好用的工具cmder

    今天来推荐一个超级好用的命令行工具:cmder 一款Windows环境下非常简洁美观易用的cmd替代者,它支持了大部分的Linux命令.支持ssh连接linux,使用起来非常方便.比起cmd.powe ...

  6. 算法学习之剑指offer(六)

    题目1 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. import java.util.*; public cl ...

  7. 【Medium 万赞好文】ViewModel 和 LIveData:模式 + 反模式

    原文作者: Jose Alcérreca 原文地址: ViewModels and LiveData: Patterns + AntiPatterns 译者:秉心说 View 和 ViewModel ...

  8. Python开发【第一篇】:目录

    本系列博文包含Python基础.前端开发.Web框架.缓存以及队列等,希望可以给正在学习Python编程的朋友们提供一点帮助! .Python开发[第一篇]:目录 .Python开发[第二篇]:初始P ...

  9. 使用python进行运动轨迹合并:多次骑行跑步轨迹叠加显示

    现有各种各样的运动app.运动手表手环以及gps码表等可以用于记录日常骑行或跑步等运动轨迹;但轨迹显示多数只限于显示一天的轨迹,经过搜索只发现一篇文章介绍跑步轨迹叠加方法(查看),根据教程尝试了下还因 ...

  10. Spring Boot入门(一):搭建Spring Boot项目

    从本篇博客开始,我们开始进入Spring Boot的世界,它的出现使Spring的开发变得更加简洁,因此一经推出受到众多程序员的喜爱. 作为Spring Boot系列的第一篇博客,我们先来讲解下如何搭 ...