基于 Session 实现短信登录
短信验证
一、基于Session
1、登录流程
1)发送验证码
用户在提交手机号后,会校验手机号是否合法,如果不合法,则要求用户重新输入手机号
如果手机号合法,后台此时生成对应的验证码,同时将验证码进行保存,然后再通过短信的方式将验证码发送给用户
2)短信验证码登录、注册
用户将验证码和手机号进行输入,
后台从session中拿到当前验证码,然后和用户输入的验证码进行校验,
如果不一致,则无法通过校验,
如果一致,则后台根据手机号查询用户,
如果用户不存在,则为用户创建账号信息,保存到数据库。
无论是否存在,都会将用户信息保存到session中,方便后续获得当前登录信息
2、实现验证码发送
使用MyBatisX实现项目的初始化
1)正则表达式
分别对手机号、密码、验证码进行校验
正则表达式可以去网上找
public class RegexPatterns {
/**
* 手机号正则
*/
public static final String PHONE_REGEX="1\\d{10}";
/**
* 邮箱正则
*/
public static final String EMAIL_REGEX="/^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$/";
/**
* 验证码正则
*/
public static final String VERIFY_CODE_REGEX="^[a-zA-Z\\d]{6}$";
}
2)正则校验工具类
controller传入的手机号进行校验
满足手机号正则表达式,手机号11位,并且只能为数字,才能校验通过
官网:https://doc.hutool.cn/pages/index/#简介
public class RegexUtils {
/**
* 校验手机号是否合法
* @param phone
* @return
*/
public static boolean isPhoneInvalid(String phone){
boolean matches = phone.matches(RegexPatterns.PHONE_REGEX);
return matches;
}
/**
* 校验验证码是否合法
* @param code
* @return
*/
public boolean isCodeInvalid(String code){
boolean matches = code.matches(RegexPatterns.VERIFY_CODE_REGEX);
return matches;
}
}
3)Controller层
@GetMapping("/code")
public boolean SendCode(String phone, HttpSession session){
boolean b = userService.sendCode(phone, session);
return b;
}
4)service层
首先对传入的手机号放到正则校验工具类中校验
校验成功后生成验证码
将验证码存入session中
将验证码在控制台以debug形式输出
@Resource
private UserService userService; public boolean sendCode(String phone, HttpSession session) {
//1、校验手机号是否合法
if (!RegexUtils.isPhoneInvalid(phone)) {
return false;
}
//2、生成随机验证吗
String code = RandomUtil.randomNumbers(6);
//3、保存验证码
session.setAttribute("code",code);
//4、打印日志
log.debug("发送短信验证码成功,验证码:{}",code);
return true;
}
注意:这里需要开启debug日志
controller层中加入@Slf4j注解
logging:
level:
com.example: debug
# 开启debug日志
结果:

3、实现验证码登录注册
短信验证登录注册逻辑:
- 校验手机号
- 校验验证码
- 取出session中保存的验证码与表单中的输入的验证码吗进行比较
- 不一致:报错
- 一致:根据手机号查询用户
- 判断用户是否存在
- 不存在,根据手机号创建新用户并保存
- 用户是凭空创建的,所以密码可以没有,
- 用户呢称和头像都是随机默认的
- 保存用户信息到session中
1)Controller层
我们登录需要获取两个参数
用户名和手机号,根据手机号来创建用户名
@PostMapping("/login")
public boolean login(LoginFormDTO loginFormDTO, HttpSession session){
boolean login = userService.Login(loginFormDTO, session);
return login;
}
为了使代码更加美观,创建一个参数封装类
/**
* 用户登录请求参数封装类
*/
@Data
public class LoginFormDTO {
private String code;
private String phone;
}
2)service层
/**
* 用户登录
* @param loginFormDTO
* @param session
* @return
*/
@Override
public boolean Login(LoginFormDTO loginFormDTO, HttpSession session) {
//1、首先校验手机号和验证码是否合法
String phone = loginFormDTO.getPhone();
if(!RegexUtils.isPhoneInvalid(phone)){
return false;
}
//2、校验验证码
Object cachecode = session.getAttribute("code");
String dtoCode = loginFormDTO.getCode();
if (dtoCode==null&&!dtoCode.equals(cachecode)) {
return false;
}
//3、根据手机号查询用户信息
QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
queryWrapper.eq("phone", phone);
//4、根据查询条件查询数据库中满足以上条件的用户
User user = userMapper.selectOne(queryWrapper);
if (user==null) {
//创建用户
user=CreateUser(phone);
}
//5、保存用户信息到session中
session.setAttribute("user",user);
return true;
}
将创建用户的这段代码单独封装为一个函数
/**
* 创建用户
* @param phone
* @return
*/
private User CreateUser(String phone){
User user = new User();
user.setPhone(phone);
user.setNickName(RandomUtil.randomString(10));
//保存用户
save(user);
return user;
}
发送验证码
get http://localhost:8080/api/user/code?phone=13177576913
校验验证码并登录
post http://localhost:8080/api/user/login?phone=13177576913
&code=686422
结果:

4、优化一:全局通用返回对象
前面我的测试前端返回的数据都太过单调,因为这是一个功能的实现,并不是做一个完整的项目,但这样看起来确实不太美观
所以这里使用==全局统一API响应框架==对整个接口进行统一的异常处理封装,这样就不需要写那么多的异常处理类了。
1)引入依赖
使用rest-api-spring-boot-starter这个依赖,不用打开Redis,但这个依赖需要加上
<!--RestfulAPI-->
<dependency>
<groupId>cn.soboys</groupId>
<artifactId>rest-api-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2)注解
启动类上加上这个注解
@EnableRestFullApi
就只需要这两步
LOG日志都不一样了

注意:
这里的端口号是8000,也就是说使用这个依赖必须要8000端口,我们在配置文件中所
设置的web端口没有用了,无法自定义端口
运行

我们先进行用户脱敏
3)用户信息脱敏
将返回对象单独封装
@Data
public class UserDTO {
private Long id;
private String nickName;
private String icon;
}
修改登录login方法中的
/**
* copyProperties:属性拷贝——把user中的属性字动拷贝到UserDTO中
* BeanUtils:使用的是包cn.hutool.core.bean下的工具类
*/
//5、保存用户信息到session中
UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
session.setAttribute("user", userDTO);
结果这里就不说了,成功返回三个信息
基于 Session 实现短信登录的更多相关文章
- 短信登录与注册接口、前端所有方式登录注册页面、redis数据库介绍与安装
今日内容概要 短信登陆接口 短信注册接口 登陆注册前端 redis介绍和安装 内容详细 1.短信登陆接口 在视图类 user/views.py中修改并添加: from .serializer impo ...
- python基于LeanCloud的短信验证
python基于LeanCloud的短信验证 1. 获取LeanCloud的Id.Key 2. 安装Flask框架和Requests库 pip install flask pip install re ...
- 基于session和cookie的登录验证(CBV模式)
基于session和cookie的登录验证(CBV模式) urls.py """cookie_session URL Configuration The `urlpatt ...
- Spring Security 解析(四) ——短信登录开发
Spring Security 解析(四) -- 短信登录开发 在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring Security ...
- 重构客户注册-基于ActiveMQ实现短信验证码生产者
重构目标:将bos_fore项目中的CustomerAction作为短信消息生产者,将消息发给ActiveMQ,创建一个单独的SMS项目,作为短信息的消费者,从ActiveMQ获取短信消息,调用第三方 ...
- SpringSecurity实现短信登录功能
⒈封装短信验证码类 package cn.coreqi.security.validate; import java.time.LocalDateTime; public class Validate ...
- 基于PHP实现短信验证码接口的方法
步骤: 1.登录荣联运通讯注册获取ACCOUNT SID.AUTH TOKEN.Rest URL(生产).AppID(默认): 2.注册测试用手机号码(先注册测试号码方可使用): 3.下载demo示例 ...
- Spring Security之短信登录
实现短信验证码登录 前面实现了 用户名+密码 的登录方式,现在实现一下短信验证码登录. 开发短信验证码接口 短信验证码和图形验证码类似,用户从手机短信得到验证码和从图片得到验证码类似. 校验短信验证码 ...
- day102:MoFang:后端完成对短信验证码的校验&基于celery完成异步短信发送&flask_jwt_extended&用户登录的API接口
目录 1.用户注册 1.后端完成对短信验证码的校验 2.基于celery实现短信异步发送 2.用户登录 1.jwt登录验证:flask_jwt_extended 2.服务端提供用户登录的API接口 1 ...
- SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能
在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...
随机推荐
- CGI、FastCGI和PHP-FPM区别和关系详解
在搭建 LAMP/LNMP 服务器时,会经常遇到 PHP-FPM.FastCGI和CGI 这几个概念.如果对它们一知半解,很难搭建出高性能的服务器.接下来我们就以图形方式,解释这些概念之间的关系. 1 ...
- 火山引擎ByteHouse发布高性能全文检索引擎
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群. 随着数字时代的发展,数据的来源和生成方式越来越广泛,数据形态也愈加丰富. 以某电商平台的数据情况举例.该电 ...
- 题解:P10417 [蓝桥杯 2023 国 A] 第 K 小的和
分析 这道题不是板子么. 先对序列排序,然后二分答案,设当前答案为 \(x\),枚举 \(a\) 中的数,然后二分查找 \(b\) 中不大于 \(x-a\) 的元素个数,累加判断是否不大于 \(k\) ...
- CF466E Information Graph 题解
题目链接 Luogu Codeforces 题意简述 某公司中有 \(n\) 名员工.为方便起见,将这些员工从 1 至 \(n\) 编号.起初,员工之间相互独立.接下来,会有以下 \(m\) 次操作: ...
- Windows11下使用VcXsrv+xfce4实现图形化窗口
通过 sudo apt-get install xfce4-terminal sudo apt-get install xfce4 sudo service dbus restart 来安装所需要的软 ...
- MySQL之DML
DQL:SELECT * FROM 表名 DML(数据操作语言,它是对表记录的操作(增.删.改)!) 1. 插入数据 * INSERT INTO 表名(列名1,列名2, ...) VALUES(列值1 ...
- centos7 最小化安装yum不能安装软件解决方案
慕课网神思者老师课常资料带的布署工具中,自带的liunx 系统centos7 yum发现不能安装软件,比如docker 解决方案 首先我们安装好虚拟机启动系统centos7 尝试安装任何软件都会报 ...
- CCF A类会议 —— AAAI2022 论文审稿模板
======================================================= 前段时间为实验室负责审理AAAI 2022的会议稿件,感觉这个审稿模板还是不错的,这里保 ...
- 【转载】 【报错】ImportError: cannot import name 'downsample' —— lasagne模块 调用 theano 报错
原网址: https://blog.csdn.net/kz_java/article/details/125030733 ======================================= ...
- baselines算法库logger.py模块分析
baselines根目录下logger.py模块代码: import os import sys import shutil import os.path as osp import json imp ...