JWT令牌
1、pom引入依赖
<!-- JWT依赖--> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
2、utils包下创建工具类
public class JwtUtils { private static String signKey = "KaiLangJiaoJiao";//签名密钥 private static Long expire = 43200000L; //有效时间 /** * 生成JWT令牌 * @param claims JWT第二部分负载 payload 中存储的内容 * @return */ public static String generateJwt(Map<String, Object> claims){ String jwt = Jwts.builder() .addClaims(claims)//自定义信息(有效载荷) .signWith(SignatureAlgorithm.HS256, signKey)//签名算法(头部) .setExpiration(new Date(System.currentTimeMillis() + expire))//过期时间 .compact(); return jwt; } /** * 解析JWT令牌 * @param jwt JWT令牌 * @return JWT第二部分负载 payload 中存储的内容 */ public static Claims parseJWT(String jwt){ Claims claims = Jwts.parser() .setSigningKey(signKey)//指定签名密钥 .parseClaimsJws(jwt)//指定令牌Token .getBody(); return claims; } }
3、Controller登录成功以后生成JWT
@RestController @Slf4j public class LoginController { @Autowired private EmpService empService; @PostMapping("/login") public Result login(@RequestBody Emp emp){ Emp user = empService.login(emp); if(user != null){ // 登录成功创建jwt令牌 Map<String,Object> map = new HashMap<>(); map.put("id",user.getId()); map.put("name",user.getName()); String jwt = JwtUtils.generateJwt(map); return Result.success(jwt); } return Result.error("账号或密码错误"); } }
过滤器
1、加入pom依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency>
2、创建filter包
package com.zsh.springboot_web.filter; import com.itheima.springboot_web.pojo.Result; import com.itheima.springboot_web.utils.JwtUtils; import lombok.extern.slf4j.Slf4j; import com.alibaba.fastjson.JSONObject; import org.springframework.util.StringUtils; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(urlPatterns = "/*") @Slf4j public class LoginFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { //前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法) HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; //1.获取请求url String url = request.getRequestURL().toString(); log.info("请求路径:{}", url); //请求路径:http://localhost:8080/login //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行 if(url.contains("/login")){ chain.doFilter(request, response);//放行请求 return;//结束当前方法的执行 } //3.获取请求头中的令牌(token) String token = request.getHeader("token"); log.info("从请求头中获取的令牌:{}",token); //4.判断令牌是否存在,如果不存在,返回错误结果(未登录) if(!StringUtils.hasLength(token)){ log.info("Token不存在"); Result responseResult = Result.error("NOT_LOGIN"); //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类) String json = JSONObject.toJSONString(responseResult); response.setContentType("application/json;charset=utf-8"); //响应 response.getWriter().write(json); return; } //5.解析token,如果解析失败,返回错误结果(未登录) try { JwtUtils.parseJWT(token); }catch (Exception e){ log.info("令牌解析失败!"); Result responseResult = Result.error("NOT_LOGIN"); //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类) String json = JSONObject.toJSONString(responseResult); response.setContentType("application/json;charset=utf-8"); //响应 response.getWriter().write(json); return; } //6.放行 chain.doFilter(request, response); } }
3、在启动类上加入@ServletComponentScan注解
package com.zsh.springboot_web; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication @MapperScan("com.itheima.springboot_web.mapper") @ServletComponentScan public class SpringbootWebApplication { public static void main(String[] args) { SpringApplication.run(SpringbootWebApplication.class, args); } }
拦截器
1、拦截报错依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency>
2、创建interceptor包
package com.zsh.springboot_web.interceptor; import com.alibaba.fastjson.JSONObject; import com.itheima.springboot_web.pojo.Result; import com.itheima.springboot_web.utils.JwtUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Component @Slf4j public class LoginInterceptor implements HandlerInterceptor { /* * 重要: * return true; // 放行 * false; // 不放行 * */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1.获取请求头中的令牌(token) String token = request.getHeader("token"); log.info("从请求头中获取的令牌:{}",token); //2.判断令牌是否存在,如果不存在,返回错误结果(未登录) if(!StringUtils.hasLength(token)){ log.info("Token不存在"); Result responseResult = Result.error("NOT_LOGIN"); //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类) String json = JSONObject.toJSONString(responseResult); response.setContentType("application/json;charset=utf-8"); //响应 response.getWriter().write(json); return false; } //3.解析token,如果解析失败,返回错误结果(未登录) try { JwtUtils.parseJWT(token); }catch (Exception e){ log.info("令牌解析失败!"); Result responseResult = Result.error("NOT_LOGIN"); //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类) String json = JSONObject.toJSONString(responseResult); response.setContentType("application/json;charset=utf-8"); //响应 response.getWriter().write(json); return false; } //4.放行 return true; } }
3、创建config包
package com.zsh.springboot_web.config; import com.itheima.springboot_web.interceptor.DemoInterceptor; import com.itheima.springboot_web.interceptor.LoginInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { // 自定义的拦截器对象 /* @Autowired private DemoInterceptor demoInterceptor;*/ @Autowired private LoginInterceptor loginInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 注册自定义拦截器对象 registry.addInterceptor(loginInterceptor).addPathPatterns("/**") // 设置拦截器拦截的请求路径(/**表示拦截所有请求) .excludePathPatterns("/login"); // 设置不拦截的请求路径 } }