当前位置: 首页 > news >正文

【第5章】SpringBoot实战篇之登录模式切换

文章目录

  • 前言
  • 一、接口扩展
    • 1. LoginStorage
    • 2. LocalLoginStorage
    • 3. RedisLoginStorage
    • 4. 参数配置
  • 二、登录相关接口改动
    • 1.登录接口
    • 2. 登录拦截器
  • 总结


前言

前面分别介绍了本地Map和redis存储用户登录信息,但是第二天我登录就出现问题了,因为我Redis部署在虚拟机里面,不可能每次都专门启动虚拟机,来回替换代码也太麻烦,这里我们根据配置参数来控制下将用户信息存储到哪里。


一、接口扩展

开放扩展,关闭修改。

1. LoginStorage

package org.example.springboot3.bigevent.login;/*** Create by zjg on 2024/6/3*/
public interface LoginStorage {public void put(String id, String token);public String get(String id);public boolean remove(String id);
}

2. LocalLoginStorage

package org.example.springboot3.bigevent.login;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** Create by zjg on 2024/6/3*/
@ConditionalOnProperty(name="login.storage",havingValue = "0")
@Component
public class LocalLoginStorage implements LoginStorage{private Map<String,String> loginUsers=new ConcurrentHashMap<>(256);@Overridepublic void put(String id, String token) {loginUsers.put(id, token);}@Overridepublic String get(String id) {return loginUsers.get(id);}@Overridepublic boolean remove(String id) {return loginUsers.remove(id)!=null;}}

3. RedisLoginStorage

package org.example.springboot3.bigevent.login;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;/*** Create by zjg on 2024/6/3*/
@ConditionalOnProperty(name="login.storage",havingValue = "1")
@Component
public class RedisLoginStorage implements LoginStorage{@AutowiredStringRedisTemplate stringRedisTemplate;@Overridepublic void put(String id, String token) {stringRedisTemplate.opsForValue().set(id,token,24, TimeUnit.HOURS);}@Overridepublic String get(String id) {return stringRedisTemplate.opsForValue().get(id);}@Overridepublic boolean remove(String id) {return Boolean.TRUE.equals(stringRedisTemplate.delete(id));}
}

4. 参数配置

这个参数控制使用本地存储、还是redis存储,这样扩展起来也方便。

login:storage: 0

二、登录相关接口改动

1.登录接口

@Autowired
LoginStorage loginStorage;
@RequestMapping("login")
public Result login(@Valid User loginUser){String message="用户名/密码不正确";User user = userSerivce.findUserByName(loginUser.getUsername());if(user!=null){//用户存在if(user.getPassword().equals(Md5Util.getMD5String(loginUser.getPassword()))){//密码正确Map<String,Object> claims=new HashMap();claims.put("userId",user.getId());claims.put("username",user.getUsername());String token = JwtUtils.create(claims);loginStorage.put(user.getId().toString(),token);return Result.success("登录成功",token);}}return Result.error(message);
}

2. 登录拦截器

@Autowired
LoginStorage loginStorage;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");if(token!=null&&token.contains("Bearer")){String tokenStr = token.substring(token.indexOf("Bearer") + 7);boolean verify = JwtUtils.verify(tokenStr);if(verify){//此处解析loginUsers,验证用户已登录Map<String, Object> claims = JwtUtils.getClaims(tokenStr);if(tokenStr.equals(loginStorage.get(claims.get("userId").toString()))){ThreadLocalUtil.set(claims);//用户信息放置ThreadLocalreturn true;};}}response.setStatus(HttpStatus.UNAUTHORIZED.value());response.setContentType("application/json;charset=UTF-8");ObjectMapper objectMapper = new ObjectMapper();objectMapper.writerFor(Result.class);String message = objectMapper.writeValueAsString(Result.error("token验证失败,请重新获取token后重试!"));response.getWriter().println(message);return false;
}

总结

回到顶部

这样我们就可以通过参数login.storage的修改,灵活地调整用户登录信息的存储方式了。
后面的登出接口和修改密码接口也会涉及到模式的使用。

相关文章:

【第5章】SpringBoot实战篇之登录模式切换

文章目录 前言一、接口扩展1. LoginStorage2. LocalLoginStorage3. RedisLoginStorage4. 参数配置 二、登录相关接口改动1.登录接口2. 登录拦截器 总结 前言 前面分别介绍了本地Map和redis存储用户登录信息&#xff0c;但是第二天我登录就出现问题了&#xff0c;因为我Redis部…...

2024最新华为OD算法题目

在一个机房中,服务器的位置标识在 n*m 的整数矩阵网格中,1表示单元格上有服务器,0 表示没有。如果两台服务器位于同一行或者同一列中紧邻的位置,则认为它们之间可以组成一个局域网。请你统计机房中最大的局域网包含的服务器个数。 输入描述 第一行输入两个正整数,n和m,…...

Redis集群方案有哪些?

今天咱们来聊聊Redis集群方案&#xff0c;想象一下Redis是个超级大的储物柜&#xff0c;里面放满了你各种各样的宝贝&#xff08;数据&#xff09;。但随着宝贝越来越多&#xff0c;一个储物柜不够用了&#xff0c;这时候我们就得想方设法扩大空间&#xff0c;还要保证找东西依…...

数字影像产业园的三大赋能:科技、创新与无限可能

数字影像产业园作为文创产业的重要载体&#xff0c;以科技为核心驱动力&#xff0c;不断推动产业的技术革新和升级。 园区内汇聚了最前沿的数字技术资源&#xff0c;高清摄影设备、虚拟现实技术、人工智能应用等尖端科技在这里得到广泛应用&#xff0c;不仅提升了生产效率&…...

枚举(enum)+联合体(union)

枚举联合 一.枚举类型1.枚举类型的声明2.枚举类型的优点3.枚举类型的使用 二.联合体1.联合体类型的声明2.联合体的特点3.相同成员的结构体和联合体对比4.联合体大小的计算5.联合体的练习&#xff08;判断大小端&#xff09;6.联合体节省空间例题 一.枚举类型 1.枚举类型的声明…...

postman教程-15-前置脚本

上一小节我们学习了Postman生成随机数的方法&#xff0c;本小节我们讲解一下Postman前置脚本的使用方法。 Postman中的前置脚本&#xff08;Pre-request Script&#xff09;允许你在发送请求之前运行JavaScript代码。这可以用于修改请求头、查询参数、请求体等&#xff0c;或者…...

AIGC会带来失业潮吗?紧紧跟时代第一步,如何学习AIGC

会&#xff0c;但AI淘汰的始终是跟不上时代的人。 现在很多公司都有AI培训&#xff0c;不仅GPT&#xff0c;还有Midjourney、Stable DIffusion等一系列AI工具。 像我们公司虽然今年招的少&#xff0c;但也会对新招的应届生统一进行AI培训。 用任正非先生的话来说就是&#x…...

C++第二十四弹---从零开始模拟STL中的list(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、基本结构 2、基本函数实现 2.1、默认构造函数 2.2、尾插数据 3、迭代器的封装 3.1、迭代器的基本结构 3.2、迭代器重载函数的实现 4、迭…...

大宋咨询(深圳社情民意调查)关于社情民意调查研究的内容

社情民意调查内容&#xff0c;是一项至关重要的社会研究活动&#xff0c;它涵盖了社会生活的方方面面&#xff0c;通过深入了解民众的需求、态度和看法&#xff0c;为决策提供了宝贵的参考依据。 首先&#xff0c;社会经济状况是社情民意调查不可或缺的一部分。这包括了对当地…...

PID算法在电机速度控制上的应用

目录 概述 1 系统硬件框架 1.1 框架介绍 1.2 硬件实物图 2 STM32Cub生成工程 2.1 软件版本信息 2.2 配置参数 ​编辑2.3 生成项目 3 PID算法实现 3.1 概念 3.2 代码实现 4 其他功能实现 4.1 设置电机速度 4.2 PID算法控制电机 4.3 功能函数的调用 5 测试 5.1 …...

埃隆·马斯克 - 从梦想家到改变世界的企业家

埃隆马斯克 - 从梦想家到改变世界的企业家 本文内容是埃隆马斯克传的重点章节精华提炼&#xff0c;介绍了马斯克传奇一生 参考资料内容&#xff1a;埃隆马斯克传&造梦者埃隆马斯克 参考资料在文末获取&#xff0c;关注我&#xff0c;分享优质前沿资料&#xff08;IT、运…...

微信小程序长图片自适应

/*wxss中的代码*/ .image-container { display:flex;width: 100%; /* 或其他需要的宽度 */ /* margin-bottom: 10px; //图片之间的间距 */height: auto; } 核心&#xff1a;要真正自适应&#xff0c;就要在wxml中加入固定宽度style“width:750rpx” /*wxml中的代码*/ &l…...

elasticsearch hanlp 插件安装操作

elasticsearch hanlp 插件安装操作 下载 hanlp 插件上传hanlp插件到elasticsearch服务器安装hanlp插件kibana测试 下载 hanlp 插件 这里大家根据自己对应的 elasticsearch 版本下载匹配版本的 hanlp 插件&#xff0c;由于 hanlp 及 elasticsearch 各个版本之间差别较大&#x…...

为什么进程和线程 ID 总是 4 的倍数?

如果您研究下任务管理器中的的进程 ID (PID)&#xff0c;则你会发现这样一个规律&#xff1a;它们都是 4 的倍数。 基于 Windows NT 内核的操作系统上&#xff0c;不止是进程 ID&#xff0c;实际上&#xff0c;线程 ID (TID) 也遵守这样的规律&#xff1a;也即它们都是 4 的倍…...

LabVIEW版本控制

LabVIEW作为一种流行的图形化编程环境&#xff0c;在软件开发中广泛应用。有效地管理版本控制对于确保软件的可靠性和可维护性至关重要。LabVIEW提供了多种方式来管理VI和应用程序的修订历史&#xff0c;以满足不同规模和复杂度的项目需求。 LabVIEW中的VI修订历史 LabVIEW内置…...

不输Kimi的AI插件——Elmo Chat (免费,无需注册)

&#x1f31a; 前阵子不是写了篇《一分钟上手AI神器——Kimi (附_ 官方提示词)》 嘛&#xff0c;给大伙安利了一波 Kimi Chat 这个AI 神器&#xff0c;不知道是不是用户量上来了&#xff0c;算力一下子跟不上&#xff0c;感觉变笨了不少&#x1f923;。在别的推文看到多轮对话后…...

使用cesiumLab使shp转为3dtlies

过程不做赘述&#xff0c;网上大把&#xff0c;说下注意事项。 1. 存储3DTiles 选项 若是打开则输出的文件为glb格式文件,因为glb文件好储存易传输跨平台。cesium可以使用但无法处理&#xff0c;例如改变颜色&#xff0c;改着色器等。若是不打开则输出的文件为bm3d格式文件,此…...

中科数安 | 透明加密防泄密系统!如何有效防止企业内部核心数据资料外泄?

中科数安提供的透明加密防泄密系统是一种专为企业设计的数据保护解决方案&#xff0c;它通过以下关键特性有效防止企业内部核心数据资料外泄&#xff1a; PC地址&#xff1a;——www.weaem.com 自动智能透明加密&#xff1a;系统能够在操作系统级别无缝集成&#xff0c;对指定类…...

go的反射和断言

在go中对于一个变量&#xff0c;主要包含两个信息变量类型&#xff08;type&#xff09;和变量值&#xff08;value&#xff09; 可以通过reflect包在运行的时候动态获取变量信息&#xff0c;并能够进行操作 对于Type可以通过reflect.TypeOf()获取到变量的类型信息 reflect.Ty…...

打造新引擎,迈向数智金融新未来

数智技术正在全面赋能金融机构转型升级以及促进金融与实体经济的加速融合&#xff0c;已呈现出金融机构数智化经营加速、产业 数字金融深度融合、数字技术驱动绿色金融发展、金融信创成果涌现、金融机构加快数字化组织管理变革等行业趋势。 根据银行业协会调研&#xff0c;78%…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...