在Spring boot中 使用JWT和过滤器实现登录认证

这篇具有很好参考价值的文章主要介绍了在Spring boot中 使用JWT和过滤器实现登录认证。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Spring boot中 使用JWT和过滤器实现登录认证

一、登录获得JWT

  1. 在navicat中运行如下sql,准备一张user表
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `id` int(11) NOT NULL,
  `username` varchar(50) NOT NULL,
  `password` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES ('1', 'root', '123', '1');
  1. 导入pom.xml坐标
		<!-- JWT依赖坐标-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>
 		<!-- 解析JSON-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.15.2</version>
        </dependency>
  1. 在工utils包下创建一个用于生成和解析JWT 令牌的工具类
public class JwtUtils {

    private static String signKey = "baisepengyuyan";//签名密钥(这个可以自定义)
    private static Long expire = 86400000L; //有效时间 1 天 = 24 小时 * 60 分钟 * 60 秒 * 1000 毫秒 = 86,400,000 milliseconds



    /*生成JWT令牌*/
    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令牌 */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)//指定签名密钥
                .parseClaimsJws(jwt)//指定令牌Token
                .getBody();
        return claims;		//返回令牌中 payload 中存储的内容(登录用户的信息)
    }
}
  1. 在pojo包下创建user类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String username;
    private String password;
}
  1. 在mapper包下添加 UserMapper接口
@Mapper
public interface UserMapper {
    @Select("select id ,username ,password from t_user where username = #{username} and password= #{password}")
    User getLoginUser(User user);
}
  1. 在service包下添加 UserService类
@Service
public class UserService {

    @Autowired
    UserMapper userMapper;

    public User login(User user) {

        User loginUser = userMapper.getLoginUser(user);

        if (loginUser == null )
            return null;

        return user;
    }
}
  1. 在utils包下添加统一响应结果封装类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code ;//1 成功 , 0 失败
    private String msg; //提示信息
    private Object data; //数据 data

    public static Result success(Object data){
        return new Result(1, "success", data);
    }
    public static Result success(){
        return new Result(1, "success", null);
    }
    public static Result error(String msg){
        return new Result(0, msg, null);
    }
    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}
  1. 在controller包下添加LoginController类
@RestController
@Slf4j
public class LoginController {
    //依赖业务层对象
    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public Result login(@RequestBody User user) {
        //调用业务层:登录功能
        User loginEmp = userService.login(user);

        //判断:登录用户是否存在
        if(loginEmp !=null ){
            //自定义信息
            Map<String , Object> claims = new HashMap<>();
            claims.put("id", loginEmp.getId());
            claims.put("username",loginEmp.getUsername());
            claims.put("name",loginEmp.getName());

            //使用JWT工具类,生成身份令牌
            String token = JwtUtils.generateJwt(claims);
            return Result.success(token);
        }
        return Result.error("用户名或密码错误");
    }
}

这样登录获取token的接口就写好了,接下来我们来用post工具来测一下这个登录接口

这里我使用的工具是Apifox

在Spring boot中 使用JWT和过滤器实现登录认证,spring boot,java,数据库

这样我们就拿到了 这个token (这个token的有效期是一天, 有效时间的长短可以在JWT工具类那里设置)

eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjpudWxsLCJpZCI6MCwidXNlcm5hbWUiOiJtYWkiLCJleHAiOjE2OTg2NTg1OTh9.aFDGnKvMOjgpZjdgXcQfaDM1ONupOvdwYtYNxPAaN6s

这样我们就将这个登录获取JWT的功能开发好了,但是, 现在我们仍然可以访问别的请求路径,不被拦截,所以我们要引入过滤器.

二、引入过滤器

​ 引入过滤器的就是为了,限制为未登录的用户。不让他们访问除了登录以外的资源。

那现在我们写一个测试用例,用于测试, 看看没引入过滤器和引入过滤器的区别

  • 在LoginController类下添加这个方法
    @GetMapping("/getResource")
    public Result getUser(){
        return Result.success("成功访问/getResource");
    }

添加完这个方法后 我们尝试访问 http://localhost:8080/getResource

在Spring boot中 使用JWT和过滤器实现登录认证,spring boot,java,数据库

这是我们可以看到用户在未登录的情况下, 仍然可以正常访问我们的资源, 这是我们不希望看到的.

那么我们开始引入过滤器

  1. 在启动类上添加 @ServletComponentScan注解
@ServletComponentScan
  1. 创建一个filter包 ,在这个包下创建 LoginCheckFilter类
@Slf4j
@WebFilter(urlPatterns = "/*") //拦截所有请求
public class LoginCheckFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        //前置:强制转换为http协议的请求对象、响应对象 (转换原因:要使用子类中特有方法)
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //创建json解析对象
        ObjectMapper objectMapper = new ObjectMapper();
        //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("Authorization");

        log.info("从请求头中获取的令牌:{}",token);

        //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if(!StringUtils.hasLength(token)){
            log.info("Token不存在");

            Result responseResult = Result.error("NOT_LOGIN");
            //把Result对象转换为JSON格式字符串

            String json = objectMapper.writeValueAsString(responseResult);
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write(json);

            return;
        }

        //5.解析token,如果解析失败,返回错误结果(未登录)
        try {

            if (token.startsWith("Bearer ")) {
                token = token.substring(7);
                log.info("切除Bearer 令牌:{}",token);
            }
            JwtUtils.parseJWT(token);
        }catch (Exception e){
            log.info("令牌解析失败!");

            Result responseResult = Result.error("NOT_LOGIN");
            //把Result对象转换为JSON格式字符串 (fastjson是阿里巴巴提供的用于实现对象和json的转换工具类)
            String json = objectMapper.writeValueAsString(responseResult);
            response.setContentType("application/json;charset=utf-8");
            //响应
            response.getWriter().write(json);

            return;
        }

        //6.放行
        chain.doFilter(request, response);

    }
}

阅读代码我们可以发现, 我们拦截了所有请求,唯独给登录请求放行

现在我们再来尝试访问

在Spring boot中 使用JWT和过滤器实现登录认证,spring boot,java,数据库

但是新的问题来了 , 我们要怎么访问这个资源呢? 对, 使用刚刚我们登录后返回的JWT令牌

我们在每次请求时都在HTTP的请求头中携带JWT令牌过去

访问 http://localhost:8080/login 获得令牌

在Spring boot中 使用JWT和过滤器实现登录认证,spring boot,java,数据库

拿到令牌后 我们访问http://localhost:8080/getResource

在请求中 添加Authorization请求头 值为 Bearer + 空格 + JWT

在Spring boot中 使用JWT和过滤器实现登录认证,spring boot,java,数据库

我们可以看到 在实际的请求总 我们多谢了一个请求头 请求头和请求参数是不一样的!!!

在Spring boot中 使用JWT和过滤器实现登录认证,spring boot,java,数据库

到此 我们已经完成了一个Spring Boot整合JWT和过滤器 完成登录验证的功能了.文章来源地址https://www.toymoban.com/news/detail-735696.html

到了这里,关于在Spring boot中 使用JWT和过滤器实现登录认证的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring Boot系列】-Spring Boot过滤器Filter

    **Filter(过滤器) 可以理解为经过一层次的过滤处理才达到使用的要求,而其实 Filter(过滤器) 就是服务器与客户端请求与响应的中间层组件,在实际项目开发中 Filter(过滤器)**主要用于对浏览器的请求进行过滤处理,将过滤后的请求再转给下一个资源。 **Filter(过滤器

    2024年02月13日
    浏览(51)
  • Spring boot 中的过滤器

    `javax.servlet.Filter`接口定义了几个方法: 其中一些经常在过滤器的实现中使用。以下是常用的几个方法: 1. `doFilter()`: 这是过滤器的核心方法,用于实现过滤器的逻辑。在该方法中,您可以对请求进行预处理、修改请求参数、验证身份、记录日志等操作,然后通过调用`Filter

    2024年02月12日
    浏览(40)
  • spring boot 过滤器&拦截器与aop

    在使用 Spring 框架时,可以通过在 web.xml 配置文件中注册过滤器,使其在请求进入 Spring 前就能够进行预处理。这样可以在请求进入 Spring MVC 的 DispatcherServlet 之前,对请求进行拦截、修改或者过滤。 过滤器在 Spring 中的应用场景包括但不限于: 字符编码过滤:通过过滤器,在

    2024年02月01日
    浏览(48)
  • Spring Boot拦截器与过滤器的区别

    在使用Spring Boot开发Web应用程序时,您可能需要在处理请求之前或之后执行某些操作。这些操作可以包括身份验证、日志记录、性能监测等。在这种情况下,您可以使用两种不同的机制:拦截器和过滤器。本文将介绍这两种机制及其区别,并提供一些示例代码来演示如何在S

    2024年02月08日
    浏览(55)
  • 在Spring Boot中注册过滤器几种方式

    1. 实现 Filter 接口并使用 @WebFilter 注解:(适用于Servlet API项目) 2. 使用Spring的 FilterRegistrationBean (推荐) 3. 定义为 Spring Bean 并手动配置到 Servlet 容器中 注意:这种方法通常在需要部署为 WAR包 到非嵌入式Servlet容器时采用。而在大多数Spring Boot应用中,建议使用前两种注册过

    2024年01月19日
    浏览(38)
  • 【深入浅出Spring Security(五)】自定义过滤器进行前后端登录认证

    在【深入浅出Spring Security(二)】Spring Security的实现原理 中小编阐述了默认加载的过滤器,里面有些过滤器有时并不能满足开发中的实际需求,这个时候就需要我们自定义过滤器,然后填入或者替换掉原先存在的过滤器。 首先阐述一下添加过滤器的四个方法(都是 HttpSecur

    2024年02月08日
    浏览(51)
  • GOLANG进阶:govalidator过滤器,MD5,JWT身份验证,redis

    引入资源包(两种方式): go get github.com/asaskevich/govalidator go get gopkg.in/asaskevich/govalidator.v10 代码( 可以写在结构体中,也可以单独使用 ): type User struct {     gorm.Model     USERNAME string `json:\\\"name\\\" validate :\\\"min=0,max=35\\\"`     PASSWOR string `validate:\\\"required\\\"`     SEX int8  ` validate :

    2024年02月16日
    浏览(42)
  • 【Spring Security系列】Spring Security 过滤器详解与基于JDBC的认证实现

    上文说到,Spring Security它是一个强大的和高度可定制的身份验证和访问控制框架。它提供了一套丰富的功能,用于保护基于Spring的应用程序。 上文又说到,在Spring Security中,过滤器(Filter)是一个重要的组件,用于处理身份验证、授权和其他安全相关的任务。 Spring Security 的

    2024年04月22日
    浏览(41)
  • 登录校验-Filter-登录校验过滤器

    目录 思路 登录校验Filter-流程 步骤 流程图 登录校验Filter-代码 过滤器类 工具类 测试登录 登录接口功能请求 其他接口功能请求 前后端联调  前端访问登录接口,登陆成功后,服务端会生成一个JWT令牌,并返回给前端,前端会将JWT令牌保存下来,在同一会话中共享JWT令牌信息

    2024年02月11日
    浏览(39)
  • 【Spring】Springboot过滤器Filter和拦截器Inteceptor详解及使用场景

    Springboot过滤器Filter和拦截器Inteceptor详解及使用场景

    2024年02月13日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包