在 Spring Boot 中实现多种方式登录(用户名、手机号、邮箱等)的不正经指南
欢迎来到一场技术与幽默交织的冒险!今天,我们将跳进 Spring Boot 的世界,探索如何通过 用户名、手机号、邮箱 等多种方式实现登录。想象一下,用户在登录时可以随心所欲地选择——就像你今天早上纠结到底是要喝美式咖啡还是拿铁!而我们要做的就是为他们提供这些选择,确保他们都能毫无阻碍地进入我们的系统。
目标? 用一种轻松而富有趣味的方式带你构建一个支持多种登录方式的 Spring Boot 项目!好了,系好安全带,让我们开始这段奇妙的代码之旅。
一、需求分析
首先,让我们明白我们要做什么。如果你还记得那些老式网站,登录方式非常单一:只允许使用用户名登录,且密码必须是8个字符的 “password123” 这种经典组合。好吧,时代已经不同了,现在的人们懒得记用户名和密码,他们更愿意使用手机、邮箱,甚至脸书、微信等社交账号来登录。为什么? 因为每个人都有点“懒得输入太多字”的心理。
因此,我们的目标很明确——让用户能有更多的选择方式来登录:
- 用户名 + 密码(这是经典款)
- 手机号 + 密码(这就很潮流了)
- 邮箱 + 密码(一看就很高端)
这就像在餐厅点菜——我们提供多样化的菜单,用户随便选,爱吃啥点啥!
二、搭建你的基础工程:项目配置
没有基础设施的建筑就是一场灾难,而没有配置文件的 Spring Boot 项目就是——废的。所以,第一步,我们要确保项目的所有配置正确无误。
在你的 pom.xml
文件中,加入我们即将用到的一些核心依赖。包括 Spring Security(因为我们要玩登录认证嘛)、JPA(因为我们要有地方存储用户信息),以及 MySQL 数据库的连接驱动。
<dependencies><!-- Spring Boot Security 依赖,用于管理我们的登录和认证 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- Spring Boot Data JPA 依赖,用来进行数据库操作 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- Spring Boot Web 依赖,用来处理 Web 请求 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MySQL Connector 依赖,毕竟数据还是要放进数据库的 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- Lombok 用来减少代码量,让我们不用再写那些烦人的 getter/setter --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>
好了,既然我们已经有了正确的配置依赖,现在就像是我们已经准备好了一杯现磨咖啡,接下来该享受喝咖啡的过程了!
三、数据库设计:让用户信息有个家
每个登录系统都需要一个地方存储用户信息,否则它就像你早上出门忘了带钥匙一样尴尬。我们要创建一个用户表来保存用户名、手机号、邮箱以及密码。这里我们使用 JPA 来简化数据库操作,不必再写那些琐碎的 SQL 语句。
@Entity
@Table(name = "users")
@Data
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username; // 用户名private String password; // 密码(重要的东西,当然要加密保存)private String email; // 邮箱private String phoneNumber; // 手机号
}
你可能会问,为什么不加个字段来存储用户的昵称、性别、兴趣爱好?嗯,那确实也是个不错的想法,但我们今天的重点是登录系统——所以先忍一忍,别跑偏了。
四、用户存储库:我们需要一些查询方式
数据库表已经有了,但我们还需要写一些代码来查询这些用户信息。为此,我们需要创建一个存储库类,用于根据用户名、手机号或者邮箱来查找用户。
public interface UserRepository extends JpaRepository<User, Long> {Optional<User> findByUsername(String username);Optional<User> findByEmail(String email);Optional<User> findByPhoneNumber(String phoneNumber);
}
瞧,这就是我们数据层的三剑客:findByUsername
、findByEmail
和 findByPhoneNumber
。有了它们,我们可以方便地从数据库中查询到用户。
五、用户认证服务:让 Spring Security 成为我们的好帮手
接下来,我们要告诉 Spring Security 如何根据不同的登录信息来加载用户。这部分代码就像是一道考题,告诉系统:“嘿,如果用户输入了个手机号或者邮箱,你该如何处理?”
@Service
public class CustomUserDetailsService implements UserDetailsService {@Autowiredprivate UserRepository userRepository;@Overridepublic UserDetails loadUserByUsername(String loginInput) throws UsernameNotFoundException {Optional<User> userOpt;// 判断输入的登录信息类型,来确定是邮箱、手机号还是用户名if (loginInput.contains("@")) {// 邮箱登录userOpt = userRepository.findByEmail(loginInput);} else if (loginInput.matches("\\d+")) {// 手机号登录userOpt = userRepository.findByPhoneNumber(loginInput);} else {// 用户名登录userOpt = userRepository.findByUsername(loginInput);}// 如果用户不存在,抛出异常User user = userOpt.orElseThrow(() -> new UsernameNotFoundException("用户不存在"));// 返回 Spring Security 所需的 UserDetails 对象return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());}
}
这个类做的事情就像是一个门卫,不管用户输入的是用户名、邮箱,还是手机号,都会验证一遍,确保用户是真实存在的。
六、密码加密:不要让用户的密码变成人人可知的小秘密
安全问题非常重要,如果我们把密码明文存储,那就相当于把家里的钥匙放在门口的地垫下面,绝对是个坏主意。幸运的是,Spring Security 自带了密码加密支持,我们可以使用 BCryptPasswordEncoder
来加密用户密码。
@Bean
public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
}
然后在用户注册时,对密码进行加密后再存入数据库:
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Autowiredprivate PasswordEncoder passwordEncoder;public void registerUser(User user) {// 密码加密user.setPassword(passwordEncoder.encode(user.getPassword()));userRepository.save(user);}
}
有了这个小魔法,所有密码都会以加密形式存储,即便有人黑进了数据库,也只能看到一串毫无意义的字符。
七、Spring Security 配置:别忘了这位主角
一部电影怎么能没有导演?而我们的导演就是 Spring Security 的配置类。我们将在这里配置登录逻辑,告诉系统如何处理不同的登录方式。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate CustomUserDetailsService userDetailsService;@Autowiredprivate PasswordEncoder passwordEncoder;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// 配置认证方式,使用我们自定义的 UserDetailsService 和密码加密方式auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 设置允许哪些 URL 可以被匿名访问http.csrf().disable().authorizeRequests().antMatchers("/login", "/register").permitAll() // 允许登录和注册页面被访问.anyRequest().authenticated() // 其他页面都需要认证.and().formLogin().loginPage("/login") // 设置自定义的登录页面.defaultSuccessUrl("/home", true) // 登录成功后跳转的页面.permitAll().and().logout().permitAll();}
}
在这段配置中,我们告诉 Spring Security 使用我们自定义的 CustomUserDetailsService
来处理登录请求。我们还设置了登录页面和成功后的重定向页面,显得很专业有木有?
八、最后的话:为用户提供选择,登录就像选咖啡一样简单
现在,我们已经成功搭建了一个支持多种方式登录的系统。不论是使用用户名、手机号还是邮箱,用户都可以自由选择,就像他们早晨选择喝哪种咖啡一样简单。而你,作为这家“咖啡店”的老板,成功地提供了更多的便利和选择!
所以,下次当你看到用户轻松登录时,可以骄傲地拍拍自己的肩膀,毕竟,你让这个世界的登录系统变得更加多样化了。
(Ps:如果用户抱怨登录总是出错,请告诉他们密码不能用“123456”,那样实在太“平庸”了点 😜)
相关文章:

在 Spring Boot 中实现多种方式登录(用户名、手机号、邮箱等)的不正经指南
欢迎来到一场技术与幽默交织的冒险!今天,我们将跳进 Spring Boot 的世界,探索如何通过 用户名、手机号、邮箱 等多种方式实现登录。想象一下,用户在登录时可以随心所欲地选择——就像你今天早上纠结到底是要喝美式咖啡还是拿铁&am…...

.NET平台用C#添加动作到PDF文档
使用C#语言在.NET框架下向PDF文档中添加动作,不仅能够提升文档的交互性和用户体验,还能够在自动化工作流中发挥关键作用,例如自动跳转至特定页面、链接外部资源或播放音频资源等操作。这种能力使得开发者能够根据具体需求定制PDF文档的互动操…...

大数据治理:概念、框架与实践应用
摘要: 随着大数据时代的到来,数据量呈爆炸式增长,数据来源和类型日益多样化。大数据治理作为确保数据质量、安全性、合规性以及有效利用数据资产的关键领域,已成为企业和组织在数字化转型过程中面临的重要挑战和机遇。本文深入探讨了大数据治理的概念,详细阐述了其涵盖的主…...

Vue.observable 全解析:Observable 是什么及使用场景剖析
Vue.observable 详解 Vue.observable 是 Vue 2.x 中的一个 API,用于将普通对象转化为响应式对象,类似于 Vue 组件中的 data 对象,可以实现数据的双向绑定。它允许你将任何普通对象转化为 Vue 响应式系统管理的对象,使得该对象的属性变化时能够自动触发视图更新。 什么是 …...

MySQL基础知识大总结
一,介绍 数据库是什么,我们在学习其他编程语言的时候会使用数组呀,链表,二叉树等等一些数据结构来存储我们的数据,但是大家有没有发现我们一旦关闭程序,所有的数据都没有了,这在发行的软件来看是…...

池化技术、Commons Pool介绍
概述 池化技术,一种通过重复利用对象实例而非频繁创建和销毁的技术。 常见的可池化对象: 数据库连接(Connection):数据库连接创建和销毁代价高,连接池广泛用于管理JDBC连接;线程(Thread):线程的创建和销…...

下载并安装Visual Studio 2017过程
一、下载 1、下载链接 下载链接:官方网址 先登录 往下滑找到较早的下载 2、进行搜索下载 或者直接点击🔗网站跳转 3、确认系统信息进行下载 二、安装 下载完成后右键使用管理员身份运行 1、点击同意后安装 2、若报错—设置失败 打开控制面板-&g…...

菊风视频能力平台开发服务正式入驻华为云云商店,成为华为云联营联运合作伙伴
日前,菊风视频能力平台开发服务正式入驻华为云云商店,成为华为云在实时音视频领域的联营联运合作伙伴。 菊风结合自身产品方案优势与华为云开放、共盈的生态优势强强联手,在推动金融行业数字化转型的路上又向前迈出了一大步。华为云云商店作为…...

springboot整合kafka
springboot整合kafka pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven…...

Python深度学习框架:PyTorch、Keras、Scikit-learn、TensorFlow如何使用?学会轻松玩转AI!
前言 我们先简单了解一下PyTorch、Keras、Scikit-learn和TensorFlow都是什么。 想象一下你要盖一座大房子。你需要砖头、水泥、工具等等,对吧?机器学习也是一样,需要一些工具来帮忙。PyTorch、Keras、Scikit-learn和TensorFlow就是四种不同的…...

【Linux】安装cuda
一、安装nvidia驱动 # 添加nvidia驱动ppa库 sudo add-apt-repository ppa:graphics-drivers/ppa sudo apt update# 查找推荐版本 sudo ubuntu-drivers devices# 安装推荐版本 sudo apt install nvidia-driver-560# 检验nvidia驱动是否安装 nvidia-smi 二、安装cudatoolkit&…...

为什么DDoS防御很贵?
分布式拒绝服务攻击(DDoS攻击)是一种常见的网络安全威胁,通过大量恶意流量使目标服务器无法提供正常服务。DDoS防御是一项复杂且昂贵的服务,本文将详细探讨为什么DDoS防御如此昂贵,并提供一些实用的代码示例和解决方案…...

将WPS的PPT 无损的用微软的PowerPoint打开
用WPS做了PPT,但是用用PowerPoint打开的时候,老是会有几张图错位。 解决方案:将wps做的PPT另存为PowerPoint的格式 参考博客:解决office的PPT和WPS的PPT不兼容的问题_office ppt和wps中代码不通用-CSDN博客 另存为的时候&#…...
【汇编】uniapp开发
UniApp是一款基于Vue.js构建的跨平台开发框架,可以用于快速开发同时运行在多个平台(包括iOS、Android、H5和小程序)的应用程序。UniApp的目标是提供一套代码即可在不同平台上运行的开发模式,从而节省开发者的时间和精力。本文将介…...

详解Oracle表的类型(二)
1.引言: Oracle数据库提供了多种表类型,以满足不同的数据存储和管理需求。本博文将对Oracle分区表及使用场景进行详细介绍。 2. 分区表 分区表是Oracle数据库中一种重要的表类型,它通过将表数据分割成多个逻辑部分来提高查询性能、管理灵活…...

Docker--通过Docker容器创建一个Web服务器
Web服务器 Web服务器,一般指网站服务器,是驻留于因特网上某种类型计算机的程序。 Web服务器可以向浏览器等Web客户端提供文档,也可以放置网站文件以供全世界浏览,或放置数据文件以供全世界下载。 Web服务器的主要功能是提供网上…...

Next.js-样式处理
#题引:我认为跟着官方文档学习不会走歪路 Next.js 支持多种为应用程序添加样式的方法,包括: CSS Modules:创建局部作用域的 CSS 类,避免命名冲突并提高可维护性。全局 CSS:使用简单,对于有传统…...

整合Springboot shiro jpa mysql 实现权限管理系统(附源码地址)
一、在开发企业级应用时,权限管理是一个至关重要的功能。本文将围绕 Spring Boot、JPA、MySQL 和 Apache Shiro,构建一个基础的权限管理系统,涵盖用户认证与授权等核心功能。 一、技术选型及框架介绍 Spring Boot:简化 Spring 应用的配置和开发。JPA:实现数据持久化,提供…...

极智嘉嵌入式面试题及参考答案
对于交叉编译器的理解 交叉编译器是一种在一个计算机平台上为另一个不同架构的计算机平台生成可执行代码的编译器。它在嵌入式系统开发中起着关键作用。 从其必要性来看,嵌入式系统通常使用的处理器架构与我们日常使用的 PC 等通用计算机不同,如 ARM、MI…...

【MySQL】数据库核心技术与应用指南
数据库的各种概念 1. 指一门学科《数据库原理与应用》。(研究如何设计实现一个数据库) 2. 指一类用来管理数据的软件。 3. 指某一个具体的数据库软件。 4. 指部署了某个数据库软件的电脑。 数据库软件 关系型数据库 1. 使用 “表” 的结构来组织数据。…...

23省赛区块链应用与维护(房屋租凭)
23省赛区块链应用与维护(房屋租凭) 背景描述 随着异地务工人员的增多,房屋租赁成为一个广阔市场。目前,现有技术中的房屋租赁是由房主发布租赁信息,租赁信息发布在房屋中介或租赁软件,租客获取租赁信息后,现场看房,并签订纸质的房屋租赁合同,房屋租赁费用通过中介或…...

深度学习4
一、手动构建模型 epoch 一次完整数据的训练过程(可细分多次训练),称为 一代训练 Batch 小部分样本对权重的更新,称为 一批数据 iteration 使用一个 Batch 的过程,称为 一次训练 步骤: 1、生成 x,y 的…...

跳绳视觉计数方案
产品概述 提供基于摄像头视觉技术的跳绳计数解决方案,可精准完成跳绳动作的实时计数,效果完全满足考试水平的要求。方案采用先进的计算机视觉算法,结合高效的模型架构,确保计数的准确性和稳定性。适用场景 学校体育考试ÿ…...

TEA加密逆向
IDA伪代码 do{if ( v15 )v17 v38; // x120x0->0x79168ba790, 输入字符串经过check1处理后字符串elsev17 v40;v18 (unsigned int *)&v17[v16]; // 0x78cbbd47fc add x12, x12, x8 ; x120x79168ba790->…...

LeetCode 404.左叶子之和
题目:给定二叉树的根节点 root ,返回所有左叶子之和。 思路:一个节点为「左叶子」节点,当且仅当它是某个节点的左子节点,并且它是一个叶子结点。因此我们可以考虑对整 node 时,如果它的左子节点是一个叶子…...

01-go入门
文章目录 Go语言学习1. 简介安装windows安装linux安装编译工具安装-goland 2. 入门2.1 Helloworld注释 2.2 变量初始化打印内存地址变量交换匿名变量作用域局部变量全局变量 2.3 常量iota 2.4 数据类型布尔整数浮点类型复数字符串定义字符串字符串拼接符定义多行字符串 map数据…...

【经典】抽奖系统(HTML,CSS、JS)
目录 1、添加参与者 2、多次添加 3、点击抽奖 功能介绍: 使用方法: 完整代码: 一个简单但功能强大的抽奖系统的示例,用于在网页上实现抽奖。 1、添加参与者 2、多次添加 3、点击抽奖 功能介绍: 参与者添加&…...

GoF设计模式——结构型设计模式分析与应用
文章目录 UML图的结构主要表现为:继承(抽象)、关联 、组合或聚合 的三种关系。1. 继承(抽象,泛化关系)2. 关联3. 组合/聚合各种可能的配合:1. 关联后抽象2. 关联的集合3. 组合接口4. 递归聚合接…...

Java后端如何进行文件上传和下载 —— 本地版
简介: 本文详细介绍了在Java后端进行文件上传和下载的实现方法,包括文件上传保存到本地的完整流程、文件下载的代码实现,以及如何处理文件预览、下载大小限制和运行失败的问题,并提供了完整的代码示例。 大体思路 1、文件上传 …...

json格式数据集转换成yolo的txt格式数据集
这个代码是参考了两个博客 我是感觉第一篇博客可能有问题,然后自己做了改进,如果我是错误的或者正确的,请各位评论区说一下,感谢 Json格式的数据集标签转化为有效的txt格式(data_coco)_train.json-CSDN博客 COCO(.j…...