Springboot集成JWT,用户名,密码生成token

news2025/1/11 2:50:17

何为token?【如果想直接看代码可以往下翻】

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
1. 客户端使用用户名跟密码请求登录
2. 服务端收到请求,去验证用户名与密码
3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里
5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

token优点

支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通
过HTTP头传输.
无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登
录用户的信息,只需要在客户端的cookie或本地介质存储状态信息.
更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服
务端只要提供API即可.
去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你
可以进行Token生成调用即可.
更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的
(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
CSRF:因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析
要费时得多.
不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理.
基于标准化:你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby,
Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)

如何创建token【我这里用的是Jwt机制,有些公司用的是自己的生成方法哈】

(1)创建maven工程,引入依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.6.0</version>
</dependency>

(2)使用工具类JwtUtils

/**
 * @author: Mr.Yang
 * @create: 2020-02-13 21:19
 **/
@Getter
@Setter
@ConfigurationProperties("jwt.config")
public class JwtUtils {
    //签名私钥
    private String key;
    //签名失效时间
    private Long failureTime;

    /**
     * 设置认证token
     *
     * @param id      用户登录ID
     * @param subject 用户登录名
     * @param map     其他私有数据
     * @return
     */
    public String createJwt(String id, String subject, Map<String, Object> map) {

        //1、设置失效时间啊
        long now = System.currentTimeMillis();  //毫秒
        long exp = now + failureTime;

        //2、创建JwtBuilder
        JwtBuilder jwtBuilder = Jwts.builder().setId(id).setSubject(subject)
                .setIssuedAt(new Date())
                //设置签名防止篡改
                .signWith(SignatureAlgorithm.HS256, key);

        //3、根据map设置claims
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            jwtBuilder.claim(entry.getKey(), entry.getValue());
        }
        jwtBuilder.setExpiration(new Date(exp));

        //4、创建token
        String token = jwtBuilder.compact();
        return token;
    }

    /**
     * 解析token
     *
     * @param token
     * @return
     */
    public Claims parseJwt(String token) {
        Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
        return claims;
    }

}

注意

@ConfigurationProperties("jwt.config")需要在配置文件中配置

 

(3)配置JwtUtils类
/**
     * 配置jwt
     *
     * @return
     */
    @Bean
    public JwtUtils jwtUtils() {
        return new JwtUtils();
    }

(4)编写登录方法

  1、编写DAO层

/**
 * @author: Mr.Yang
 * @create: 2020-02-13 21:55
 **/
@Repository
public interface UserDAO {

    public User selectByMobileUser(String mobile);

    public User selectByIdUser(String id);
}

  2、编写xml写Sql

<select id="selectByMobileUser" parameterType="string" resultMap="userMap">
        select *
        from bs_user
        where mobile = #{mobile}
    </select>

  3、编写service层

/**
     * 根据mobile查询用户
     *
     * @param mobile
     * @return
     */
    public User selectByMobile(String mobile) {
        return userDAO.selectByMobileUser(mobile);
    }

  4、编写controller层

/**
     * 用户登录
     * 1.通过service根据mobile查询用户
     * 2.比较password
     * 3.生成jwt信息
     *
     * @param loginMap
     * @return
     * @requestBody把请求数据封装(前端以json方式传)
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Result login(@RequestBody Map<String, String> loginMap) {
        String mobile = loginMap.get("mobile");
        String password = loginMap.get("password");
        User user = userService.selectByMobile(mobile);
        //登录失败
        if (user == null || !user.getPassword().equals(password)) {
            //既可以使用抛异常,也可使用直接返回错误码(推荐)
            return new Result(ResultCode.MOBILEORPASSWORDERROR);
        } else {
            //其他数据以map集合存放在token中
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("companyId", user.getCompanyId());
            dataMap.put("companyName", user.getCompanyName());
            //生成token并存入数据返回
            String token = jwtUtils.createJwt(user.getId(), user.getUsername(), dataMap);
            return new Result(Result.SUCCESS(), token);
        }
    }

  5、测试

data就是返回的token,里面存有用户ID,用户姓名及以map形式存入的数据(这里主要看前端需要什么就存什么)


(6)用户登录成功之后,获取用户信息

/**
     * 用户登录成功之后,获取用户信息
     * 1.获取用户id
     * 2.根据用户id查询用户
     * 3.构建返回值对象
     * 4.响应
     *
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/profile", method = RequestMethod.POST)
    public Result profile(HttpServletRequest request) throws PendingException, Exception {

        /**
         * 从请求头信息中获取token数据
         *   1.获取请求头信息:名称=Authorization(前后端约定)
         *   2.替换Bearer+空格
         *   3.解析token
         *   4.获取clamis
         */


        //1.获取请求头信息:名称=Authorization(前后端约定)
        String authorization = request.getHeader("Authorization");
        if (StringUtils.isEmpty(authorization)) {
//            throw new PendingException(ResCode.UNAUTHENTICATED);
            //系统未捕捉到请求头信息
            throw new CommonException(ResultCode.UNAUTHENTICATED);
        }
        //2.替换Bearer+空格
        String token = authorization.replace("Bearer ", "");

        //3.解析token
        Claims claims = jwtUtils.parseJwt(token);
        //4.获取clamis
        String userId = claims.getId();

        //  String userId = "U01";
        User user = userService.selectByIdUser(userId);

        /**此处只是为了获取token中的用户数据,所有只简单返回用户对象,
         * 工作则按实际要求多表查询需要数据(根据用户ID查询权限)
         */

        return new Result(ResultCode.SUCCESS, user);
    }

(7)测试

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

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

相关文章

【java:牛客每日三十题总结-6】

java:牛客每日三十题总结 总结如下 总结如下 transient 变量和序列化有关&#xff0c;这是一个空接口&#xff0c;起标记作用&#xff0c;具体的序列化由ObjectOutputStream和ObjectInputStream完成。transient修饰的变量不能被序列化&#xff0c;static变量不管加没加transie…

Linux基础开发工具之调试器gdb

文章目录 1.编译成的可调试的debug版本1.1gcc test.c -o testdebug -g1.2readelf -S testdebug | grep -i debug 2.调试指令2.0quit退出2.1list/l/l 数字: 显示代码2.2run/r运行2.3断点相关1. break num/b num: 设置2. info b: 查看3. d index: 删除4. n: F10逐过程5. p 变量名…

聊一聊 Solid 和 Vue 框架有啥差异性?

Solid.js和Vue.js都是JavaScript框架&#xff0c;在开发者社区中引起了相当大的关注和采用。每个框架都满足了不同的需求和偏好&#xff0c;具有独特的方法论、理念和特性。本文旨在对它们进行评估&#xff0c;探讨它们的基本理念、架构、可用性、性能等方面。 让我们从两个简短…

一文搞懂设计模式之单例模式

大家好&#xff0c;我是晴天&#xff0c;本周我们一起来学习单例模式。本文将介绍单例模式的基本属性&#xff0c;两种构造单例的方法&#xff08;饿汉模式和懒汉模式&#xff09;以及golang自带的sync.Once()方法。 什么是单例模式 GoF对单例模式的定义是&#xff1a;保证一个…

Python实战 | 使用 Python 和 TensorFlow 构建卷积神经网络(CNN)进行人脸识别

专栏集锦&#xff0c;大佬们可以收藏以备不时之需 Spring Cloud实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏&#xff1a;https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏&#xff1a;https:/…

从C++软件调试实战的角度去看多线程编程中的若干细节问题

目录 1、线程与线程函数基础知识 1.1、创建线程的函数返回时不代表代码执行到线程函数中了 1.2、创建线程的函数返回后要调用CloseHandle将线程句柄&#xff08;引用计数&#xff09;释放掉 1.3、线程何时退出并结束&#xff1f; 2、线程函数的几个细节 3、回调函数运行在…

CenterOS 安装 Jira 需求/BUG管理工具

一、Jira 安装配置 1.1 安装 Jira 下载安装包 https://product-downloads.atlassian.com/software/jira/downloads/atlassian-jira-software-9.5.0-x64.bin将下载的安装包上传至服务器中。 创建 jira 安装目录和数据存放目录 mkdir -p /opt/jira/data添加可运行权限 chmo…

线性代数理解笔记

一.向量引入: 向量&#xff1a;只由大小和方向决定&#xff0c;不由位置决定。 二.向量加减法 向量的加法是首尾相连&#xff0c;减法是尾尾相连。 而向量v向量w为平行四边形主对角线。 向量v-向量w为平行四边形副对角线。 2.向量内积点乘&#xff08;内积&#xff09; 内积…

八种架构设计模式优缺点

目录 1、软件架构 2、架构设计模式 2.1、单库单应用模式 2.2、内容分发模式 2.3、查询分离模式 2.4 微服务模式 2.5 多级缓存模式 1、软件架构 软件架构是指对软件系统整个结构和组成部分之间的关系进行抽象和定义的过程&#xff0c;旨在解决系统设计和实现过程中的复杂…

CSS注入的四种实现方式

目录 CSS注入窃取标签属性数据 简单的一个实验&#xff1a; 解决hidden 方法1&#xff1a;jsnode.js实现 侧信道攻击 方法2&#xff1a;对比波兰研究院的方案 使用兄弟选择器 方法3&#xff1a;jswebsocket实现CSS注入 实验实现&#xff1a; 方法4&#xff1a;window…

ROC 曲线详解

前言 ROC 曲线是一种坐标图式的分析工具&#xff0c;是由二战中的电子和雷达工程师发明的&#xff0c;发明之初是用来侦测敌军飞机、船舰&#xff0c;后来被应用于医学、生物学、犯罪心理学。 如今&#xff0c;ROC 曲线已经被广泛应用于机器学习领域的模型评估&#xff0c;说…

「题解」反转链表 返回中间节点

文章目录 &#x1f349;题目1&#xff1a;反转链表&#x1f349;解析&#x1f34c;解法一&#xff1a;创建一个新链表&#x1f34c;解法二&#xff1a;直接操作原链表 &#x1f349;题目2&#xff1a;返回中间节点&#x1f34c;解法一&#xff1a;快慢指针&#x1f34c;解法二&…

2023年【汽车驾驶员(高级)】找解析及汽车驾驶员(高级)复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车驾驶员&#xff08;高级&#xff09;找解析是安全生产模拟考试一点通总题库中生成的一套汽车驾驶员&#xff08;高级&#xff09;复审考试&#xff0c;安全生产模拟考试一点通上汽车驾驶员&#xff08;高级&#…

【Linux】WSL安装Kali及基本操作

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍WSL安装Kali及基本操作。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路…

采用示波器显示扭矩传感器模拟信号

扭矩传感器输出的信号波形通常是模拟电压信号&#xff0c;可以通过示波器等仪器进行分析。扭矩传感器的输出信号波形通常有两种类型&#xff1a;正弦波和方波。 应变片传感器扭矩测量采用应变电测技术。在弹性轴上粘贴应变计组成测量电桥&#xff0c;当弹性轴受扭矩产生微小变…

IPV4过渡IPV6的关键技术NAT(Network AddressTranslation,网络地址转换)

文章目录 NAT的由来NAT基本工作机制NAT技术的分类推荐阅读 NAT的由来 随着物联网、工业互联网、5G的快速发展&#xff0c;网络应用对IP地址的需求呈现出爆炸式的增长。 然而&#xff0c;早在2011年&#xff0c;ICANN就发布公告称最后五组IP地址已分配完毕&#xff0c;已无IPv4…

华为ensp搭建小型园区网络规划

文章目录 前言一、拓扑图二、数据规划三、设备配置四.配置命令1.配置接入层交换机ACC11.1 设备命名&#xff0c;创建VLAN1.2 配置eth-trunk 11.3 配置用户端 2.配置核心层交换机CORE2.1设备命名2.2配置Eth-Trunk2.3 vlan配置ip2.4 上行接口配置 3.DHCP配置3.1 CORE: 4.配置路由…

【CASS精品教程】cass3d 11.0加载超大影像、三维模型、点云数据

CAD2016+CASS11.0(内置3d)下载与安装: 【CASS精品教程】CAD2016+CASS11.0安装教程(附CASS11.0安装包下载)https://geostorm.blog.csdn.net/article/details/132392530 一、cass11.0 3d支持的数据 cass11.0中的3d模块增加了多种数据的支持,主要有: 1. 三维模型 点击…

Python文件、文件夹操作汇总

目录 一、概览 二、文件操作 2.1 文件的打开、关闭 2.2 文件级操作 2.3 文件内容的操作 三、文件夹操作 四、常用技巧 五、常见使用场景 5.1 查找指定类型文件 5.2 查找指定名称的文件 5.3 查找指定名称的文件夹 5.4 指定路径查找包含指定内容的文件 一、概览 ​在…

Least Square Method 最小二乘法(图文详解,必懂)

最小二乘法是一种求解线性回归模型的优化方法&#xff0c;其目标是最小化数据点和拟合直线之间的残差平方和。这意味着最小二乘法关注的是找到一个直线&#xff0c;使得所有数据点与该直线的偏差的平方和最小。在数学公式中&#xff0c;如果y是实际值&#xff0c;y是函数估计值…