【Redis】短信登录-Part1 如何基于Session实现短信登录

这个系列主要针对对Redis的系统学习,会逐步利用redis来做一些缓存实战

有关当前模型

手机或者app端发起请求,请求我们的nginx服务器,nginx基于七层模型走的是HTTP协议,可以实现基于Lua直接绕开tomcat访问redis,也可以作为静态资源服务器,轻松扛下上万并发, 负载均衡到下游tomcat服务器,打散流量,我们都知道一台4核8G的tomcat,在优化和处理简单业务的加持下,大不了就处理1000左右的并发, 经过nginx的负载均衡分流后,利用集群支撑起整个项目,同时nginx在部署了前端项目后,更是可以做到动静分离,进一步降低tomcat服务的压力,这些功能都得靠nginx起作用,所以nginx是整个项目中重要的一环。

在tomcat支撑起并发流量后,我们如果让tomcat直接去访问Mysql,根据经验Mysql企业级服务器只要上点并发,一般是16或32 核心cpu,32 或64G内存,像企业级mysql加上固态硬盘能够支撑的并发,大概就是4000起~7000左右,上万并发, 瞬间就会让Mysql服务器的cpu,硬盘全部打满,容易崩溃,所以我们在高并发场景下,会选择使用mysql集群,同时为了进一步降低Mysql的压力,同时增加访问的性能,我们也会加入Redis,同时使用Redis集群使得Redis对外提供更好的服务。

对于短信登录实现方法有多种,例如session,jwt

使用Session和使用JWT(JSON Web Token)实现用户认证和授权的方式有一些区别,先说一下它们之间的主要区别:

  1. 存储方式

    • Session:Session存储在服务器端,通常存储在内存或数据库中。服务器会为每个会话分配一个唯一的Session ID,并将Session ID存储在客户端的Cookie中。

    • JWT:JWT是一种基于JSON的令牌,包含用户信息和签名。JWT生成后可以存储在客户端的LocalStorage或SessionStorage中,服务器无需保存任何状态信息。

  2. 状态管理

    • Session:需要在服务器端维护Session状态,包括Session ID、用户信息等。服务器需要消耗一定的资源来管理Session状态。

    • JWT:无状态,服务器端不需要维护任何状态信息,所有信息都包含在JWT中。这样可以减轻服务器的负担,提高可伸缩性。

  3. 安全性

    • Session:Session基于服务器端存储,相对安全。但可能存在会话劫持、跨站点请求伪造(CSRF)等安全风险。

    • JWT:JWT包含签名和加密信息,可以确保数据的完整性和安全性。但如果JWT泄露,攻击者可以解码其中的信息。

  4. 扩展性

    • Session:需要在服务器端维护Session状态,可能会影响系统的扩展性和性能。

    • JWT:无状态,可以轻松扩展到多个服务实例或跨域服务。

虽然JWT看起来更好一点,但是为了巩固一下各种实现方法,先将session的说一下

1.基于Session实现登录流程

基于session实现登录主要分为三个流程

  • 发送短信验证码

  • 短信验证码登录、注册

  • 校验登录状态

具体流程看下方流程图:

2.实现发送短信验证码功能

既然我们要校验验证码,我们就需要知道如何生成验证码?如何保存验证码?如何发送验证码?

生成验证码:可以利用随机数生成

保存验证码:只需要将验证码保存在session会话中就行

发送验证码:我们先用log日志模拟发送验证码,后期在相关业务中再选择对应的发送方式

代码如下:

  • 发送验证码

@Override
public Result sendCode(String phone, HttpSession session) {
    // 1.校验手机号
    if (RegexUtils.isPhoneInvalid(phone)) {
        // 2.如果不符合,返回错误信息
        return Result.fail("手机号格式错误!");
    }
    // 3.符合,生成验证码
    String code = RandomUtil.randomNumbers(6);
​
    // 4.保存验证码到 session
        session.setAttribute("code",code);
    // 5.发送验证码
    log.debug("发送短信验证码成功,验证码:{}", code);
    // 返回ok
    return Result.ok();
}

发送验证码之后就需要登录校验

具体逻辑:校验手机号是否合法->校验验证码是否一致->如果一致,验证码校验通过/如果不一致,报错->校验通过需要根据手机号去查询是否有该用户->如果不存在,创建一个user->将用户信息保存到session中

那么就引出了一个简单的问题,为什么要保存到session中?

原因是服务器会为每个会话分配一个唯一的Session ID,并将Session ID存储在客户端的Cookie中,可以理解为用户在登录的时候会在浏览器生成一个cookie,在这个cookie中存有session id,而每一个会话对应一个session id,该用户在不同页面进行操作的时候也可以保持用户信息,确保能够持续使用

代码如下:

  • 登录

 @Override
    public Result login(LoginFormDTO loginForm, HttpSession session) {
        // 1.校验手机号
        String phone = loginForm.getPhone();
        if (RegexUtils.isPhoneInvalid(phone)) {
            // 2.如果不符合,返回错误信息
            return Result.fail("手机号格式错误!");
        }
        // 3.校验验证码
        Object cacheCode = session.getAttribute("code");
        String code = loginForm.getCode();
        if(cacheCode == null || !cacheCode.toString().equals(code)){
             //3.不一致,报错
            return Result.fail("验证码错误");
        }
        //一致,根据手机号查询用户
        User user = query().eq("phone", phone).one();
​
        //5.判断用户是否存在
        if(user == null){
            //不存在,则创建
            user =  createUserWithPhone(phone);
        }
        //7.保存用户信息到session中
        session.setAttribute("user",user);
​
        return Result.ok();
    }

  • 33
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值