SpringBoot集成JWT实现权限认证
上一篇文章《一分钟带你了解JWT认证!》介绍了JWT的组成和认证原理,本文将介绍下SpringBoot整合JWT实现认证的过程,带你更深入的了解下JWT。
一、JWT认证流程
认证流程如下:
- 用户使用账号和密码发出post请求;
- 服务器使用私钥创建一个jwt;
- 服务器返回这个jwt给浏览器;
- 浏览器将该jwt串在请求头中像服务器发送请求;
- 服务器验证该jwt;
- 返回响应的资源给浏览器。
二、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实现权限认证的更多相关文章
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- springboot之JWT实现权限认证
1.在pom.xml添加依赖 <dependency> <groupId>com.auth0</groupId> <artifactId>java-jw ...
- SpringBoot集成JWT 实现接口权限认证
JWT介绍 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的, 特别适用于分布式站点 ...
- springboot使用jwt进行权限验证
springboot使用jwt进行权限验证 依赖准备 首先导入对应的依赖 <dependencies> <dependency> <groupId>org.apac ...
- SpringBoot集成JWT实现token验证
原文:https://www.jianshu.com/p/e88d3f8151db JWT官网: https://jwt.io/ JWT(Java版)的github地址:https://github. ...
- spring-boot整合shiro作权限认证
spring-shiro属于轻量级权限框架,即使spring-security更新换代,市场上大多数企业还是选择shiro 废话不多说 引入pom文件 <!--shiro集成spring--& ...
- SpringBoot集成JWT
JWT(json web tokens)是目前比较流行的跨域认证解决方案:说通俗点就是比较流行的token生成和校验的方案.碰巧公司有个app的项目的token采用了jwt方案,因此记录下后端 ...
- SpringBoot整合JWT实现登录认证
什么是JWT Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点 ...
- springboot集成shiro实现权限缓存和记住我
到这节为止,我们已经实现了身份验证和权限验证.但是,如果我们登录之后多次访问http://localhost:8080/userInfo/userDel的话,会发现权限验证会每次都执行一次.这是有问题 ...
随机推荐
- .NET进阶篇-丑话先说,Flag先立
作为开发者,工作了几年,也总觉得技术栈和刚毕业区别不大,用的技术还都是N年前的,每每看到新东西,也只心里哇塞惊叹一下,然后就回归于忙碌.怪自己的技术池太浅,热门的令人称奇的技术也都是在其他巨人的肩膀上 ...
- BERT论文解读
本文尽量贴合BERT的原论文,但考虑到要易于理解,所以并非逐句翻译,而是根据笔者的个人理解进行翻译,其中有一些论文没有解释清楚或者笔者未能深入理解的地方,都有放出原文,如有不当之处,请各位多多包含,并 ...
- TCP/UDP的小事情
UDP: 没有复杂的控制机制,面向无连接的通信服务. 常用于: 包总量少的通信 音视频传输(即时通信) TCP: 对传输.发送.通信.进行控制的协议.面向有连接的协议,只有在确认通信对端存在时才会发送 ...
- dedecms织梦二次开发报名表单模块插件安装及配置详细教程
网上找了很多,都不是太满意,功能不全不全不说,还没有详细的安装配置教程,经过自己的折腾,成功了修改程序并配置成功,亲测,试用没有问题!所以,决定给大家出一个针对新手的详细教程. 废话不多,直接上干货. ...
- 关于MySQL的经典例题50道
--1.学生表Student(S,Sname,Sage,Ssex) --S 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别--2.课程表 Course(C,Cname,T) - ...
- 新手学分布式-动态修改Nginx配置的一些想法
本人是分布式的新手,在实际工作中遇到了需要动态修改nginx的需求,因此写下实现过程中的想法.Nginx功能强大且灵活,所以这些权当抛砖引玉,希望可以得到大家的讨论和指点.(具体代码在 https:/ ...
- Java求和的整体思路
一. 设计思想: 设计这个程序我们需要考虑到参数的输入,并且可以输入多个参数,以及为用户考虑到各种的边界问题.首先第一步我们应该给出输入参数的语句,让用户可以输入.第二步我们应对其进行参数个数的 ...
- 最长上升子序列 LIS nlogn
给出一个 1 ∼ n (n ≤ 10^5) 的排列 P 求其最长上升子序列长度 Input 第一行一个正整数n,表示序列中整数个数: 第二行是空格隔开的n个整数组成的序列. Output 最长上升子序 ...
- django rest framework1
内容回顾: 1.开发模式 - 普通开发方式(前后端放在一起写) - 前后端分离 2.后端开发 为前端提供URL(API/接口的开发) 注:永远返回HttpResponse 3.Django FBV.C ...
- 机器学习:不平衡信息有序平均加权最近邻算法IFROWANN
一 背景介绍 不平衡信息,特点是少数信息更珍贵,多数信息没有代表性.所以一般的分类算法会被多数信息影响,而忽略少数信息的重要性. 解决策略: 1.数据级别 (1)上采样:增加稀有类成本数 (2)下采样 ...