SpringBoot学习足迹

1、Json web token(JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC 7519),该token被设计为紧凑且安全的,特别适用于分布式站点的单点登陆(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。JWT听起来很复杂,其实原理很简单,比如我们可以自己生成一个guid字符串+key+附加信息加密作为token传递到客户端也能达到同样目的。

2、pom.xml增加如下代码来添加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版本中文乱码,设置UTF-8不起作用,修改字体如下

以下几部分内容主要参考
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("/login"); //登录 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

截止目前项目结构如下

上一节:SpringBoot学习- 3、整合MyBatis

SpringBoot学习- 4、整合JWT的更多相关文章

  1. 玩转 SpringBoot 2 之整合 JWT 上篇

    前言 该文主要带你了解什么是 JWT,以及JWT 定义和先关概念的介绍,并通过简单Demo 带你了解如何使用 SpringBoot 2 整合 JWT. 介绍前在这里我们来探讨一下如何学习一门新的技术, ...

  2. 玩转 SpringBoot 2 之整合 JWT 下篇

    前言 在<玩转 SpringBoot 2 之整合 JWT 上篇> 中介绍了关于 JWT 相关概念和JWT 基本使用的操作方式.本文为 SpringBoot 整合 JWT 的下篇,通过解决 ...

  3. SpringBoot学习之整合Mybatis

    本博客使用IDEA开发工具,通过Maven构建SpringBoot项目,初始化项目添加的依赖有:spring-boot-starter-jdbc.spring-boot-starter-web.mys ...

  4. SpringBoot学习之整合Druid的简单应用

    一.Druid介绍 Druid简介 Druid是目前Java语言中最好的数据库连接池之一.结合了 C3P0.DBCP 等 DB 池的优点,同时加入了日志监控.Druid 是一个分布式的.支持实时多维 ...

  5. SpringBoot学习之整合Swagger

    Swagger介绍 1.什么是Swagger 作为后端程序开发,我们多多少少写过几个后台接口项目,不管是编写手机端接口,还是目前比较火热的前后端分离项目,前端与后端都是由不同的工程师进行开发,那么这之 ...

  6. SpringBoot学习:整合Mybatis,使用HikariCP超高性能数据源

    一.添加pom依赖jar包: <!--整合mybatis--> <dependency> <groupId>org.mybatis.spring.boot</ ...

  7. springboot学习2 整合mybatis

    springboot整合mybatis 一.添加mybatis和数据库连接的依赖 <!--整合mybatis--> <dependency> <groupId>or ...

  8. SpringBoot学习:整合shiro(身份认证和权限认证),使用EhCache缓存

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)在pom.xml中添加依赖: <properties> <shi ...

  9. SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)

    首先在shiro配置类中注入rememberMe管理器 /** * cookie对象; * rememberMeCookie()方法是设置Cookie的生成模版,比如cookie的name,cooki ...

  10. SpringBoot学习:整合shiro(rememberMe记住我后自动登录session失效解决办法)

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 定义一个拦截器,判断用户是通过记住我登录时,查询数据库后台自动登录,同时把用户放入ses ...

随机推荐

  1. 最新咕咆+鲁班+图灵+享学+蚂蚁+硅谷+源码 Java架构师资料《Java架构师VIP课程》

    最新的Java架构师完整资料,完整视频+源码+文档. 每一套都是一百多个G的资料,无密. JAVA架构师全套课程 咕泡学院互联网架构师第一期 咕泡学院互联网架构师第二期 咕泡学院互联网架构师第三期 博 ...

  2. java代码生成器 快速开发平台 二次开发 外包项目利器 springmvc SSM后台框架源码

    .   权限管理:点开二级菜单进入三级菜单显示 角色(基础权限)和按钮权限      角色(基础权限): 分角色组和角色,独立分配菜单权限和增删改查权限.      按钮权限: 给角色分配按钮权限.2 ...

  3. Numerical Testing Reportes of A New Conjugate Gradient Projection Method for Convex Constrained Nonlinear Equations

    Numerical Testing Reportes of A New Conjugate Gradient Projection Method for Convex Constrained Nonl ...

  4. ACM模板_axiomofchoice

    目录 语法 c++ java 动态规划 多重背包 最长不下降子序列 计算几何 向量(结构体) 平面集合基本操作 二维凸包 旋转卡壳 最大空矩形 | 扫描法 平面最近点对 | 分治 最小圆覆盖 | 随机 ...

  5. nodejs 使用 body-parser 获取网页内容

    var bodyParser = require('body-parser'); var urlencodedParser = bodyParser.urlencoded({ extended: fa ...

  6. 在腾讯云上配置.NetCoreWeb

    1.购买服务器 2.远程登录(账号密码在上图铃铛里的消息里) 3.安装iis 3.安装.NetCore相关 下载最新版本.NET Core Windows Server Hosting https:/ ...

  7. 纪中20日c组模拟赛

    赛后感想 多写点东西总是好的,但是在最后,算法就不要改动了(就这样我少了10分) 题解 T1 2121. 简单游戏 T2 2122. 幸运票

  8. 【巨杉数据库SequoiaDB】巨杉Tech | 分布式数据库千亿级超大表优化实践

    01 引言 随着用户的增长.业务的发展,大型企业用户的业务系统的数据量越来越大,超大数据表的性能问题成为阻碍业务功能实现的一大障碍.其中,流水表作为最常见的一类超大表,是企业级用户经常碰到的性能瓶颈. ...

  9. SQL Server database – Error 3743

    Database mirroring must be removed before you drop SQL Server database – Error 3743 If you try to dr ...

  10. Office办公软件Excel使用整理

    Office办公软件Excel使用整理 Excel默认打印预览于当前连接的打印机的纸张大小保持一致. Excel sheet不见了怎么办 -------------- 设置Excel第二页打印开始的位 ...