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

news2024/11/15 9:40:47

目录

1、JWT定义

1、1 JWT工作流程

1、2 JWT优点

2、添加依赖项到pom.xml 

3、创建用户实体类

 4、实现认证服务

5、登录请求处理

6、生成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 

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt</artifactId>
  <version>0.9.1</version>
</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;
    }

}

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

,结束!下课!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/547603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tolua源码分析(五)lua使用C#的enum

tolua源码分析&#xff08;五&#xff09;lua使用C#的enum 上一节我们讨论了C#类是如何注册到lua的过程&#xff0c;以及lua调用C#函数时底层所做的事情。在此基础之上&#xff0c;本节我们来看看C#的enum是如何注册到lua的&#xff0c;它和一般类的注册有哪些区别。 老规矩&a…

互联网医院资质代办|互联网医院牌照的申请流程

随着互联网技术的不断发展&#xff0c;互联网医疗已经逐渐成为人们关注的热点话题。而互联网医院作为互联网医疗的一种重要形式&#xff0c;也越来越受到社会各界的关注。若想开展互联网医院业务&#xff0c;则需要具备互联网医院牌照。那么互联网医院牌照的申请流程和需要的资…

算法——归并排序和计数排序

Ⅰ. 归并排序 1. 基本思想 归并排序&#xff08; MERGE-SORT &#xff09;是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法&#xff08; Divide and Conquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;…

Python爬虫| 一文掌握XPath

本文概要 本篇文章主要介绍利用Python爬虫爬取付费文章&#xff0c;适合练习爬虫基础同学&#xff0c;文中描述和代码示例很详细&#xff0c;干货满满&#xff0c;感兴趣的小伙伴快来一起学习吧&#xff01; &#x1f31f;&#x1f31f;&#x1f31f;个人简介&#x1f31f;&…

公司来了个00后,我愿称之为卷王之王,卷的让人崩溃...

前几天我们公司一下子来了几个新人&#xff0c;看样子好像都是一些00后&#xff0c;这些年轻人是真能熬啊&#xff0c;本来我们几个老油子都是每天稍微加会班就打算下班走了&#xff0c;这几个新人一直不走&#xff0c;搞得我们也不好提前走。 2023年春招已经过去了&#xff0…

网络安全前景怎么样?怎么自学?看这一篇就够了

一、网络安全前景 网络安全行业细分岗位比较多&#xff0c;目前需求量比较大的几类网络安全岗位有渗透测试、安全运维、等保测评等&#xff0c;在岗位需求量和薪资待遇方面都比较可观。 这时很多人就会问&#xff0c;网络安全人才需求量这么大&#xff0c;进入行业的人就会越来…

【redis】案例--迷你版微信抢红包

系列文章目录 文章目录 系列文章目录前言在这里插入图片描述 一、业务描述二、需求分析三、架构设计关键点拆红包算法 二倍均值算法 图解 四、编码实现 RedPackageController整体思路&#xff1a;发红包代码进入拆分红包算法抢红包代码 五、多学一手 前言 一、业务描述 二、需求…

鲁棒优化入门(四)——超详细讲解:两阶段鲁棒优化以及列与约束生成算法(CCG)的matlab+yalmip代码实现

本文的主要参考文献&#xff1a; Zeng B , Zhao L . Solving Two-stage Robust Optimization Problems by A Constraint-and-Column Generation Method[J]. Operations Research Letters, 2013, 41(5):457-461. 1.两阶段鲁棒优化问题的引入 鲁棒优化是应对数据不确定性的一种优…

从零玩转设计模式之单例模式-danlimos

title: 从零玩转设计模式之单例模式 date: 2022-12-12 12:41:03.604 updated: 2022-12-23 15:35:29.0 url: https://www.yby6.com/archives/danlimos categories: - 单例模式 - 设计模式 tags: - Java模式 - 单例模式 - 设计模式 前言 单例设计模式是23种设计模式中最常用的设…

面试题背麻了,花3个月面过华为测开岗,拿个26K不过分吧?

计算机专业&#xff0c;代码能力一般&#xff0c;之前有过两段实习以及一个学校项目经历。第一份实习是大二暑期在深圳的一家互联网公司做前端开发&#xff0c;第二份实习由于大三暑假回国的时间比较短&#xff08;小于两个月&#xff09;&#xff0c;于是找的实习是在一家初创…

基于 ZYNQ 的电能质量系统高速数据采集系统设计

随着电网中非线性负荷用户的不断增加 &#xff0c; 电能质量问题日益严重 。 高精度数据采集系统能够为电能质 量分析提供准确的数据支持 &#xff0c; 是解决电能质量问题的关键依据 。 通过对比现有高速采集系统的设计方案 &#xff0c; 主 控电路多以 ARM 微控制器搭配…

抖音seo排名系统/账号矩阵源码关键词开发部署

抖音seo排名系统/账号矩阵源码关键词开发技术 如何提高 抖音 搜索排名&#xff1f;如何优化抖音搜索排名&#xff1f; 部分代码分析&#xff1a;场景&#xff1a;创建一个Tree()函数来实现以下特性&#xff0c;当我们需要时&#xff0c;所有中间对象 branch1、branch2 和 bra…

Mysql常见的索引模型

目录 有序数组哈希表二叉搜索树B-TreeBTree 有序数组 我们指定一个列为索引&#xff0c;然后按照这个列的值排序&#xff0c;以有序数据存放入数据表中&#xff0c;如下所示 这样&#xff0c;我们在查找数据的时候&#xff0c;就可以通过id这个列&#xff0c;在数据表中进行二…

阿里 P8 整理的《百亿级并发系统设计》实战手册,实在是太香了

面试官问&#xff1a;如何设计一个高并发系统&#xff1f; 说实话&#xff0c;如果面试官问你这个题目&#xff0c;那么你必须要使出全身吃奶劲了。为啥&#xff1f;因为你没看到现在很多公司招聘的 JD 里都是说啥有高并发经验者优先。 如果你确实有真才实学&#xff0c;在互…

9-《数据结构》

[TOC](9-《数据结构》 一、数组1.稀疏数组 二、链表三、队列四、栈五、树5.1 完全二叉树5.2 满二叉树&#xff1a;深度为k且有2^k-1个结点的二叉树称为满二叉树**5.3 二叉排序树&#xff08;二叉搜索树、二叉查找树&#xff09;5.4 平衡二叉树&#xff1a;5.5 红黑树 六、堆七、…

文件夹加密码的方法有哪些?文件夹加密方法盘点

在我们使用电脑的过程中&#xff0c;我们会将一些重要的数据放入文件夹内进行统一管理&#xff0c;为了保护数据安全&#xff0c;文件夹加密码通常是一个不错的选择。那么文件夹该怎么加密码呢&#xff1f;电脑文件夹加密码的方法有哪些呢&#xff1f; 文件夹加密码方法 首先…

opencv读取图片

opencv是一款非常强大的图像处理库&#xff0c;可以用来进行图像的处理。opencv库提供了丰富的工具&#xff0c;比如图像缩放&#xff0c;旋转&#xff0c;倾斜校正&#xff0c;自动对齐等等&#xff0c;使用这些工具可以很方便的进行图像的处理。那么你知道 opencv怎么读取图片…

Java学习笔记-04

目录 静态成员 mian方法 多态 抽象类 接口 内部类 成员内部类 静态内部类 方法内部类 匿名内部类 静态成员 static关键字可以修饰成员方法&#xff0c;成员变量被static修饰的成员&#xff0c;成员变量就变成了静态变量&#xff0c;成员方法就变成了静态方法static修…

Java流程控制(一)

⭐ 控制语句⭐ 条件判断结构(选择结构)⭐ switch 语句 做任何事情事情都要遵循一定的原则&#xff0c;毕竟不以规矩&#xff0c;不成方圆&#xff0c;例如&#xff0c;到图书馆去借书&#xff0c;就必须要有借书证&#xff0c;并且借书证不能过期&#xff0c;这两个条件缺一不可…

【新星计划回顾】第二篇学习计划-通过定义变量简单批量模拟数据

&#x1f3c6;&#x1f3c6;又到周末&#xff0c;最近这段时间非常忙&#xff0c;虽然导师首次参与新星计划活动已经在4月16日圆满结束&#xff0c;早想腾出时间来好好整理活动期间分享的知识点。 &#x1f3c6;&#x1f3c6;非常感谢大家的支持和活动期间的文章输出&#xff0…