Redis框架(三):大众点评项目 基于Session的短信登录

news2024/11/21 0:32:29

大众点评项目 基于Session的短信登录

  • 需求:基于Session实现短信验证登录
  • 基于Session的短信登录
    • 发送手机验证码
    • 实现登录 (注意MyBatisP的接口使用)
  • 新的问题

SpringCloud章节复习已经过去,新的章节Redis开始了,这个章节中将会回顾Redis实战项目 大众点评
主要依照以下几个原则

  1. 基础+实战的Demo和Coding上传到我的代码仓库
  2. 在原有基础上加入一些设计模式,stream+lamdba等新的糖
  3. 通过DeBug调试,进入组件源码去分析底层运行的规则和设计模式

代码会同步在我的gitee中去,觉得不错的同学记得一键三连求关注,感谢:
Session-链接: RedisProjectDemo
Redis优化-链接: RedisProject

需求:基于Session实现短信验证登录

本项目是一个前后端分离项目,系统框架和展示如下
在这里插入图片描述
在这里插入图片描述
我们希望在登录可以通过短信验证方式进行注册/登录

基于Session的短信登录

在这里插入图片描述

我们获得前端参数,实现登录验证功能

我们先给出架构图

在这里插入图片描述

发送手机验证码

    @PostMapping("code")
    public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {
        // TODO 发送短信验证码并保存验证码
//        return Result.fail("功能未完成");
        return userService.sendCode(phone, session);
    }
public interface IUserService extends IService<User> {

    Result sendCode(String phone, HttpSession session);

    Result login(LoginFormDTO loginForm, HttpSession session);
}

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Result sendCode(String phone, HttpSession session) {
        if(RegexUtils.isPhoneInvalid(phone)){
            return Result.fail("手机号码格式错误!");
        }
        String code = RandomUtil.randomNumbers(6);
		//模拟发短信,将验证码放到session
       session.setAttribute("code", code);

        log.debug("发送短信验证码成功: "+ code);
        return Result.ok();
    }

实现登录 (注意MyBatisP的接口使用)

在这里插入图片描述

  1. @RequestBody是为了封装信息,实现自动配置
  2. @RequestParam对应了前端传来的参数对应
    /**
     * 登录功能
     * @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码
     */
    @PostMapping("/login")
    public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){
        // TODO 实现登录功能
//        return Result.fail("功能未完成");
        return userService.login(loginForm, session);
    }
public interface IUserService extends IService<User> {

    Result sendCode(String phone, HttpSession session);

    Result login(LoginFormDTO loginForm, HttpSession session);
}

    @Override
    public Result login(LoginFormDTO loginForm, HttpSession session) {
		//从前端拿到对应的手机号
        String phone = loginForm.getPhone();
        if ((RegexUtils.isPhoneInvalid(phone))) {
            return Result.fail("手机格式错误!");
        }


        String code = loginForm.getCode();
        //获取对应的code
		 Object cacheCode = session.getAttribute("code");

        if (cacheCode == null || !cacheCode.toString().equals(code)) {
            return Result.fail("验证码错误!");
        }
		
		// 这里是MyBatisP的命令
        User user = query().eq("phone", phone).one();
		
		//如果没有就去创建一个User
        if(user==null){
            user = createUserWithPhone(phone);
        }
		//将user通过BeanUtil工具类封装到DTO对象
        session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));

        return Result.ok();
    }

将user通过BeanUtil工具类封装到DTO对象,可以大大减少不必要数据的传输
所以设置了DTO层封装数据处理

    private User createUserWithPhone(String phone) {
        User user = new User();
        user.setPhone(phone);
        
        user.setNickName(USER_NICK_NAME_PREFIX + RandomUtil.randomString(8));
        save(user);
        return user;
    }
  1. 通过ThreadLocal存放当前对象,实现全局获取效果;
public class UserHolder {
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();

    public static void saveUser(UserDTO user){
        tl.set(user);
    }

    public static UserDTO getUser(){
        return tl.get();
    }

    public static void removeUser(){
        tl.remove();
    }
}

  1. 实现拦截器进行登录验证
    因为要对 限制的资源进行验证,所以使用了拦截器来进行处理;
    在这里插入图片描述
public class LoginInterceptor1 implements HandlerInterceptor {

    private StringRedisTemplate stringRedisTemplate;

    public LoginInterceptor1(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Object user = request.getSession().getAttribute("user");

        if (user == null) {
            response.setStatus(401);
            return false;
        }

        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        
        UserHolder.saveUser(userDTO);
        return true;

    }


    @Override
    public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception
    ex) throws Exception {
//保存到当前线程中,直接remove即可
        UserHolder.removeUser();
        System.out.println("123");
    }


}

这里的构造注入是因为
private StringRedisTemplate stringRedisTemplate; public LoginInterceptor1(StringRedisTemplate stringRedisTemplate) { this.stringRedisTemplate = stringRedisTemplate; } 这里的LoginInterceptor是通过new来实现的,没有配置到Bean工厂中去,所以通过这种方式实现
后面的配置类中会进行注入

@Configuration
public class MvcConfig implements WebMvcConfigurer {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
	            registry.addInterceptor(new LoginInterceptor())
                    .excludePathPatterns(
                            "/shop/**",
                            "voucher/**",
                            "shop-type/**",
                            "upload/**",
                            "/blog/hot",
                            "/user/code",
                            "/user/login"
                    );
	}
}

这里是为了拦截请求,做限制处理

在这里插入图片描述

在这里插入图片描述

新的问题

在这里插入图片描述

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

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

相关文章

C#语言实例源码系列-实现无损压缩图片

专栏分享点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册 &#x1f449;关于作者 众所周知&#xff0c;人生是一个漫长的流程&#xff0c;不断克服困难&#xff0c;不断反思前进的过程。在这个过程中…

微电网两阶段鲁棒优化问题(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Redis之相关介绍、远程docker部署以及相关shell命令

Redis相关shell命令一、概述1、介绍2、作用3、特性4、官方网址二、远程服务Docker上Redis相关测试及命令1、Redis安装及挂载1.1 查找所有关于Redis1.2 拉取最高版本的Redis1.3 通过xftp连接到远程服务器1.4 挂载1.5 开启远程服务器的端口1.6 修改配置文件2、开始使用Redis2.1 开…

autoconf-archive源码安装

0. 源码地址 autoconf-archive源码下载地址经由https://savannah.gnu.org搜索"autoconf-archive"到GNU Autoconf Archive - Summary [Savannah] 再在其中点击上图中箭头位置&#xff0c;转到GitHub - autoconf-archive/autoconf-archive: A mirror of the GNU Autoc…

数据分析软件-FineReport内置SQl提交

1. 概述 1.1 版本 报表服务器版本 功能变动 11.0.2 填报配置表时支持从数据库中模糊搜索表&#xff0c;详情见 2.2 节。 1.3 功能介绍 设计好填报表格&#xff0c;添加填报控件之后&#xff0c;如下图所示&#xff1a; 需要将填报数据的单元格与数据库表字段进行绑定&#…

【微服务】2、一篇文章详解 Ribbon 负载均衡

Ribbon 负载均衡一、负载均衡原理&#xff08;debug 源码&#xff09;(1) 基本介绍(2) 打断点① LoadBalancerInterceptor.java - intercept()② RibbonLoadBalancerClient.java - execute()③ RibbonLoadBalancerClient.java - execute()④ RibbonLoadBalancerClient.java - g…

【STM32】详解RTC实时时钟的概念和配置示例代码

一、什么是RTC RTC(Real-time Clock)&#xff1a;实时时钟&#xff0c;本质上是一个支持BCD编码的定时器/计数器。主电源断电后能够由电池供电&#xff0c;使其时钟跳转依然正常。 二、STM32F4芯片内的RTC功能 ①日历时钟&#xff08;时分秒、年月日、星期&#xff09; ②两个闹…

六、排序算法介绍3

4、希尔排序 4.1 简单插入排序问题 简单的插入排序可能存在的问题&#xff0c;数组 arr { 2, 3, 4, 5, 6, 1 } 这时需要插入的数 1(最小)&#xff0c;简单插入排序的过程如下&#xff1a; {2,3,4,5,6,6} {2,3,4,5,5,6} {2,3,4,4,5,6} {2,3,3,4,5,6} {2,2,3,4,5,6} {1,2,3,4,…

CCIA技术沙龙 | “数据安全风险评估及安全服务实践” 沙龙成功举办

2022年12月8日&#xff0c;由中国网络安全产业联盟&#xff08;CCIA&#xff09;主办、CCIA数据安全工作委员会支持、杭州美创科技股份有限公司承办的“数据安全风险评估及数据安全服务实践”主题技术沙龙成功举办。 当前&#xff0c;我国数字经济快速发展、数字化转型持续深入…

Java对象深拷贝详解(List深拷贝)

1、Java中拷贝的概念 在Java语言中&#xff0c;拷贝一个对象时&#xff0c;有浅拷贝与深拷贝两种 浅拷贝&#xff1a;只拷贝源对象的地址&#xff0c;所以新对象与老对象共用一个地址&#xff0c;当该地址变化时&#xff0c;两个对象也会随之改变。 深拷贝&#xff1a;拷贝对…

一起学习用Verilog在FPGA上实现CNN----(一)总体概述

1 总体概述 为避免闭门造车&#xff0c;找一个不错的开源项目&#xff0c;学习在FPGA上实现CNN&#xff0c;为后续的开发奠定基础 1.1 项目链接 大佬的开源项目链接&#xff1a; CNN-FPGA 链接跳转界面如下&#xff1a; 大佬的该项目已经发表论文&#xff0c;而且开源工程结…

Qt5.6.1移植海思Hi3521d(一)

系列文章目录 文章目录系列文章目录前言一、开发环境二、搭建环境1.准备2.海思SDK和交叉编译器安装2.测试交叉编译器一下3.安装tftp总结前言 上半年做个一个Qt移植海思芯片的程序&#xff0c;感觉差不多快忘记了&#xff0c;赶紧记录一下 一、开发环境 系统&#xff1a;Ubunt…

初学Python到月入过万最快的兼职途径(纯干货)

程序员小猴紫&#xff0c;不错过任何一次干赚钱干货 1.兼职薪资&#xff0c;附行哥工资单2.兼职门槛&#xff0c;附学习知识清单3.兼职途径&#xff0c;附入职考核过程4.我的兼职感受 答应小猴紫的第一篇赚钱干货推文来啦&#xff0c;行哥第一个在读书期间通过兼职赚到的10w收…

Web前端大作业—里约热内卢奥运会(html+css+javascript)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

产品经理 - 产品设计方法论需求分析部分

整体 – 产品设计方法论思维导图 个人整理&#xff0c;存在异议大家可以讨论下 需求分析方法论 需求分析为需求收集的延展&#xff0c;需求收集后即需进行需求分析&#xff0c;拆解需求后方可业务落地&#xff0c;此处我将其分为两步&#xff0c;一是主动发散型需求分析&am…

移动端项目(第十九课)Vite+Vant组件环境配置

常用到的环境配置时不我待(第十八课)项目环境搭建_星辰镜的博客-CSDN博客 在上面的环境的基础上加上下面的一下配置 Normalize.css: Make browsers render all elements more consistently. (necolas.github.io) 介绍 | Pinia 中文文档 (web3doc.top) Day.js 中文文档 - 2kB 大…

【Java版oj】day02排列子序列

目录 一、原题再现 二、问题分析 三、完整代码 一、原题再现 链接&#xff1a;排序子序列_牛客笔试题_牛客网 来源&#xff1a;牛客网 [编程题]排序子序列 热度指数&#xff1a;10105 时间限制&#xff1a;C/C 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C 32M&…

水果店引流活动推荐_分享水果店微信小程序制作步骤

试试做个小程序拯救你的店&#xff01;让你做出有效果的活动&#xff0c;每笔钱都花在刀刃上&#xff01; 第一&#xff0c;提升水果销量&#xff0c;降低损耗 用水果店小程序做拼团、砍价、秒杀活动&#xff0c;并讲原本卖不完的水果&#xff0c;做成果盘吸引客人注册会员。上…

Manufactoria介绍及各关卡解法

Manufactoria解法Manufactoria基本介绍解法RobotoastRoboManufactoria基本介绍 Manufactoria是一个以制造工厂为背景的程序设计游戏。在游戏中&#xff0c;玩家需要在有限的平面空间中巧妙地排布传送带&#xff0c;打点器与分支器&#xff0c;完成识别或改写特定模式的字符串的…

6.AOP之转账案例

数据准备 CREATE TABLE account (id int(11) NOT NULL,name varchar(100) NOT NULL,money decimal(7,2) NOT NULL,create_time datetime(6) NOT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;insert into account values(1,"steven",10000,"2022…