Spring boot框架 JWT实现用户账户密码登录验证

简介: Spring boot框架 JWT实现用户账户密码登录验证

1、JWT定义

JWT(JSON Web Token)是一种用于在网络应用间传递信息的安全传输方式。它是一种紧凑且自包含的方式,通过使用数字签名来验证数据的完整性和真实性。

JWT由三部分组成,使用.进行分隔:

  1. Header(头部):包含JWT的类型(typ)和使用的签名算法(alg)等信息。
  2. Payload(负载):包含要传输的数据,例如用户身份信息、权限等。它是JWT的主要内容,可以自定义添加其他需要的字段。
  3. Signature(签名):使用指定的算法对Header和Payload进行签名,以确保数据在传输过程中没有被篡改。

1、1 JWT工作流程

  1. 用户使用有效的身份凭证(如用户名和密码)向服务器发送登录请求。
  2. 服务器验证用户身份信息,如果验证通过,生成一个JWT并将其返回给客户端。
  3. 客户端在后续的请求中将JWT添加到请求的头部、查询参数或Cookie中进行传递。
  4. 服务器接收到请求后,使用密钥验证JWT的签名和完整性,并从中提取出有效的用户信息和权限等数据进行处理。
  5. 如果JWT验证通过,服务器处理请求并返回响应给客户端。

1、2 JWT优点

  优点包括:

  • 简单:JWT使用JSON格式存储信息,易于理解和使用。
  • 自包含:JWT中携带了用户的信息和权限等数据,避免了频繁查询数据库的开销。
  • 可扩展:JWT的负载部分可以自定义添加需要的字段。
  • 跨平台和语言支持:JWT在各种平台和编程语言中都有对应的实现和支持。
  • 无状态:JWT本身是无状态的,服务器不需要保存用户的会话信息,提高了可伸缩性。

2、添加依赖项到pom.xml

1. <dependency>
2.     <groupId>org.springframework.boot</groupId>
3.     <artifactId>spring-boot-starter-security</artifactId>
4. </dependency>
5. 
6. <dependency>
7.   <groupId>io.jsonwebtoken</groupId>
8.   <artifactId>jjwt</artifactId>
9.   <version>0.9.1</version>
10. </dependency>

3、创建用户实体类

创建一个表示用户的实体类,例如User,其中包含用户名和密码等属性。

如下:

4、实现认证服务

创建一个类实现Spring Security的UserDetailsService接口,用于加载用户信息。在该类中,根据用户名查询数据库,获取用户信息,包括密码。

    public List<UserEntity> findAllService() {
        return userMapper.findAllUser();
    }
    public ResultResponse login(String name,String password) {
        UserEntity user=userMapper.checkPassword(name,password);
        if(user != null){
            //不等于null就开始颁发jwt
            String token = jwtUtils.generateToken(name);
            System.out.println(token);
            return ResultResponse.returnToken(ResultResponse.success("颁发token成功",token));
        }
        return ResultResponse.illegalToken();
    }
    public ResultResponse info(String token) {
        String tokenString = token;
        String subject = JwtUtils.getSubject(tokenString);
        UserDTO userinfo=userMapper.getUserByUsername(subject);
        int status=userinfo.getStatus();
        if(status==1){
            String role=userinfo.getRoleName();
            Map<String, Object> map = new HashMap<>();
            String[] roles = {role};
            map.put("name", userinfo.getName());
            map.put("avatar", userinfo.getAvatar());
            map.put("roles", roles);
            return ResultResponse.returnToken(ResultResponse.success("用户信息获取成功",map));
        }
        return ResultResponse.returnToken(ResultResponse.fail("用户已经被禁用",userinfo));
    }

5、登录请求处理

创建一个登录请求处理的Controller,用于处理用户登录请求。在该Controller中,接收用户名和密码参数,并进行认证。

    @CrossOrigin
    @PostMapping("/user/login")
    public ResultResponse login(@RequestBody UserEntity user) {
        String username = user.getUsername();
        String password = user.getPassword();
        // 生成JWT并返回给客户端,用户名和密码正确就生成jwt
        return userService.login(username,password);
    }

6、生成JWT

在认证成功后,使用JJWT库生成JWT,并将JWT作为响应返回给客户端.

@Component
public class InterceptorConfig implements WebMvcConfigurer {
    private JdbcTemplate jdbcTemplate;
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptor() {
            //给前端输出json的方法
            private void returnJson(HttpServletResponse response, String json) throws Exception{
                PrintWriter writer = null;
                try {
                    writer = response.getWriter();
                    writer.write(json);
                } catch (IOException e) {
                } finally {
                    if (writer != null)
                        writer.close();
                }
            }
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                System.out.println("已经进入拦截器");
                // 设置跨域访问的响应头信息
                response.setHeader("Access-Control-Allow-Origin", "*");
                response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
                response.setHeader("Access-Control-Max-Age", "3600");
                response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Token");
                response.setCharacterEncoding("UTF-8");
                response.setContentType("text/html; charset=utf-8");
                // 获取tokenHeader
                String tokenHeader = request.getHeader("x-token");
                System.out.println("前端传入X-Token是============="+tokenHeader);
                // 进行token合法性验证
                if(!JwtUtils.validateToken(tokenHeader)){
                    String jsonString = JSON.toJSONString(ResultResponse.illegalToken());
                    returnJson(response,jsonString);
                    System.out.println("未放行!!!");
                    return false;
                }
                // 鉴权操作
                String path = request.getRequestURI();
                String sub = JwtUtils.getSubject(tokenHeader);
                System.out.println(path);
                // 从数据库中查询用户角色id
                Integer roleId = jdbcTemplate.queryForObject("SELECT role FROM tskj_user WHERE name = ?", Integer.class, sub);
                String targets = jdbcTemplate.queryForObject("SELECT targets FROM tskj_role WHERE id = ?", String.class, roleId);
                String tarid = jdbcTemplate.queryForObject("SELECT id FROM tskj_target WHERE target = ? and status=1", String.class, path);
                if (targets.contains(tarid)) {
                    System.out.println("拥有此节点权限:"+path);
                } else {
                    String jsonString = JSON.toJSONString(ResultResponse.illegalToken());
                    returnJson(response,jsonString);
                    System.out.println("不拥有此节点权限:"+path);
                    return false;
                }
                return true;
            }
            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//                System.out.println("请求处理完毕,但还没有进行视图渲染");
            }
            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//                System.out.println("整个请求处理完成,视图已渲染完毕");
            }
        }).addPathPatterns("/**/*").excludePathPatterns("/tskj/user/login","/static/*","/tskj/setting/getSetData","/tskj/user/logout");
        System.out.println("拦截器已经初始化并添加成功");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
    public InterceptorConfig(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
}

以上步骤是一个基本的实现流程。

,结束!下课!


相关文章
|
4月前
|
SQL Java 测试技术
在Spring boot中 使用JWT和过滤器实现登录认证
在Spring boot中 使用JWT和过滤器实现登录认证
254 0
|
2月前
|
JSON 安全 算法
|
2月前
|
存储 安全 Java
|
2月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
26天前
|
JavaScript NoSQL Java
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
CC-ADMIN后台简介一个基于 Spring Boot 2.1.3 、SpringBootMybatis plus、JWT、Shiro、Redis、Vue quasar 的前后端分离的后台管理系统
36 0
|
2月前
|
存储 JSON 算法
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
文章介绍了JWT令牌的基础教程,包括其应用场景、组成部分、生成和校验方法,并在Springboot中使用JWT技术体系完成拦截器的实现。
95 0
JWT令牌基础教程 全方位带你剖析JWT令牌,在Springboot中使用JWT技术体系,完成拦截器的实现 Interceptor (后附源码)
|
2月前
|
JavaScript
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(二)
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(一)
37 0
|
2月前
|
存储 JSON JavaScript
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(一)
Node.js单点登录SSO详解:Session、JWT、CORS让登录更简单(一)
96 0
|
4月前
【Azure APIM】在APIM中实现JWT验证不通过时跳转到Azure登录页面
【Azure APIM】在APIM中实现JWT验证不通过时跳转到Azure登录页面
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
162 1