SpringBoot+Redis实现短信登录或者手机号码绑定

当我们需要使用某个APP时,我们需要进行注册,绑定手机号码,我们都需要输入手机号,获取一个60s的验证码,然后进行验证码的校验,当超过60s时,提醒例如:验证码超时,请重新获取之类。。。。,下面小编就带大家简单的具体实现一次(适合萌新!!!)。

首先我们需要使用Idea还是Eplice创建一个springboot的项目,引入Lombok、spring Web、spring Data Redis(Access+Driver)。模板我们使用Thymeleaf。

其次去官网下载Redis,官方网址https://redis.io/ ,下载完成并安装并启动服务端。

 启动成功,项目创建完成,整体项目结构

编写配置文件。

# 应用服务 WEB 访问端口
server.port=8080
# THYMELEAF (ThymeleafAutoConfiguration)
# 开启模板缓存(默认值: true )
spring.thymeleaf.cache=true
# 检查模板是否存在,然后再呈现
spring.thymeleaf.check-template=true
# 检查模板位置是否正确(默认值 :true )
spring.thymeleaf.check-template-location=true
#Content-Type 的值(默认值: text/html )
spring.thymeleaf.content-type=text/html
# 开启 MVC Thymeleaf 视图解析(默认值: true )
spring.thymeleaf.enabled=true
# 模板编码
spring.thymeleaf.encoding=UTF-8
# 要被排除在解析之外的视图名称列表,⽤逗号分隔
spring.thymeleaf.excluded-view-names=
# 要运⽤于模板之上的模板模式。另⻅ StandardTemplate-ModeHandlers( 默认值: HTML5)
spring.thymeleaf.mode=HTML5
# 在构建 URL 时添加到视图名称前的前缀(默认值: classpath:/templates/ )
spring.thymeleaf.prefix=classpath:/templates/
# 在构建 URL 时添加到视图名称后的后缀(默认值: .html )
spring.thymeleaf.suffix=.html

# 连接超时时间
spring.redis.timeout=10
# 端口,默认为6379
spring.redis.port=6379
 # 地址
spring.redis.host=127.0.0.1
# 密码
spring.redis.password=
#jedis和lettuce都可以
#最大连接数据库连接数,设 0 为没有限制
spring.redis.jedis.pool.max-active=8
#最大等待连接中的数量,设 0 为没有限制
spring.redis.jedis.pool.max-idle=8
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。
spring.redis.jedis.pool.max-wait=-1
#最小等待连接中的数量,设 0 为没有限制
spring.redis.jedis.pool.min-idle=0



创建一个RedisConfig的类,可以直接使用。

package com.tc.config;


import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @author: wtc
 * @date 2023/6/29 10:15
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport{

    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        //参照StringRedisTemplate内部实现指定序列化器
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(keySerializer());
        redisTemplate.setHashKeySerializer(keySerializer());
        redisTemplate.setValueSerializer(valueSerializer());
        redisTemplate.setHashValueSerializer(valueSerializer());
        return redisTemplate;
    }

    private RedisSerializer<String> keySerializer(){
        return new StringRedisSerializer();
    }

    //使用Jackson序列化器
    private RedisSerializer<Object> valueSerializer(){
        return new GenericJackson2JsonRedisSerializer();
    }
}

 创建一个状态类Message

package com.tc.vo;

import lombok.Data;

/**
 * @author: wtc
 * @date 2023/6/29 11:28
 */
@Data
public class Message {

    /** 登录成功 返回状态 1 */
    public static final String ONE  = "1";

    /** 登录失败 验证码错误返回状态 2 */
    public static final String TWO  = "2";

    /** 登录失败 验证码失效返回状态 3 */
    public static final String THREE  = "3";
}

启动成功后编写一个login的html,大家可以直接复制。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
    <p>
        电话:<input type="text" id="tel" name="tel" style="outline: none;line-height: 20px">
        <button id="getCode" style="width: 80px;line-height: 26px;border: none;cursor: pointer;">
            <span id="codeText">
                获取验证码
            </span>
        </button>
    </p>
    <p>
        验证码:<input type="text" id="code" name="code" style="outline: none;line-height: 20px">
    </p>
    <p>
        <button id="login">登录</button>
    </p>


<script>
    $('#getCode').click(function (){
        $('#codeText').html('60s')
        var count = 60
        var tel = $('#tel').val()
        var timer = setInterval(function() {
            var codeText = $('#codeText').html()
            codeText = codeText.substring(0,codeText.indexOf('s'))
            $('#codeText').html(parseInt(codeText)-1+'s')
            count = count-1
            if (count<0){
                $('#codeText').html('重新发送')
                clearTimeout(timer)
            }
        }, 1000)
        $.ajax({
            url:'getCode',
            type:'get',
            data:{'tel':tel},
            success:function (data){

            }
        })
    })

    $("#login").click(function (){
        var inputCodes = $('#code').val()
        $.ajax({
            url:'checkCode',
            type:'post',
            data:{"inputCodes": inputCodes},
            success:function (data){
                if (data=='1'){
                    alert("登陆成功")
                }else if (data=='2'){
                    alert("验证码输入错误")
                }else{
                    alert("验证码失效")
                }
            }
        })
    })
</script>
</body>
</html>

启动项目,localhost:8080,编写一个controller初始化页面

package com.tc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author: wtc
 * @date 2023/6/29 9:57
 */
@Controller
public class LoginController {

    @RequestMapping("")
    public String loginPage(){
        return "login";
    }
}

点击发送验证码后向后端发送一个请求,生成一个验证码发送到手机上。

引入依赖

<dependency>
   <groupId>com.zhenzikj</groupId>
   <artifactId>zhenzisms</artifactId>
   <version>2.0.2</version>
</dependency>

后端将生成的验证码存到Redis中,并且设置有效时间60s。这里小编使用的时RedisTemplate,或者也可以使用StringRedisTemplate。二者区别具体可以自己查询一下,这里就不过多介绍了, 输入生成的验证码,点击登录,会弹出登陆成功或者失败,60s后点击登录,提示验证码失效。

具体Controller

package com.tc.controller;

import com.tc.vo.Message;
import com.zhenzi.sms.ZhenziSmsClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author: wtc
 * @date 2023/6/29 9:56
 */
@Controller
public class CodeController {

    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping(value = "getCode",method = {RequestMethod.GET})
    @ResponseBody
    public String getCode(HttpServletRequest request) throws Exception {

        String tel = request.getParameter("tel");

        /** 以下使用榛子云短信 向客户端发送短信 首次注册免费体验一次 */
        ZhenziSmsClient client = new ZhenziSmsClient("https://sms_developer.zhenzikj.com", "113269", "NjllMzc3YmYtOWEwNy00ODA1LTg3ZTgtYjU1NTg0ZTM1OGI1");

        String codes = "";
        for (int i=0;i<5;i++){
            codes =  (int) (Math.random() * 10) + codes;
        }
        Map<String, Object> params = new HashMap<String, Object>();

        /** 电话号码 */
        params.put("number", tel);
        
        /** 模板的id */
        params.put("templateId", "11838");
        String[] templateParams = new String[2];

        /** 验证码 */
        templateParams[0] = codes;

        /** 时间 */
        templateParams[1] = "60s";
        params.put("templateParams", templateParams);

        /** 将参数传到client服务器上 */

        client.send(params);
        redisTemplate.opsForValue().set("codes",codes);
        redisTemplate.expire("codes",60, TimeUnit.SECONDS);
        System.out.println("验证码为--------------" + codes);
        return codes;
    }

    @RequestMapping(value = "checkCode",method = {RequestMethod.POST})
    @ResponseBody
    public String checkCode(HttpServletRequest request){
        String inputCodes = request.getParameter("inputCodes");
        String codes = (String) redisTemplate.opsForValue().get("codes");
        if (codes == null || "".equals(codes)){
            return Message.THREE;
        }
        if (inputCodes.equals(codes)){
            return Message.ONE;
        }
        return Message.TWO;
    }
}

*榛子云短信具体使用

注册地址http://sms_developer.zhenzikj.com/zhenzisms_user/register.html

注册完成进入

ZhenziSmsClient client = new ZhenziSmsClient(apiUrl, appId, appSecret);

apiUrl:https://sms_developer.zhenzikj.com

appId:如上截图AppId

appSecret:图上截图的AppSecret

找到短信模板 里面的模板id是我们上面需要

 补充:

参数名称必选类型描述
templateIdstring短信模板ID,登录用户中心,在"短信管理->短信模板"中创建,并查看
templateParamsstring[]短信模板参数
numberstring接收者手机号码
messageIdstringmessageId即该条短信的唯一标识, 不能重复
clientIpstring客户端IP,需要与应用设置中的”客户IP限额“配合使用,主要防止用户恶意刷短信

启动主类CheckCodeApplication,并开启缓存

运行成功

 点击获取验证码

手机上也会受到短信验证码。

今天分享就到这里,需要源码私信。。。。欢迎各位大佬多提意见! 

Spring Boot结合Redis实现登录功能通常涉及以下几个步骤: 1. **添加依赖**: 在`pom.xml`中添加Spring Data RedisSpring Security的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> ``` 2. **配置Redis**: 在`application.properties`中设置Redis连接信息: ``` spring.redis.host=localhost spring.redis.port=6379 ``` 3. **配置Security**: 创建`SecurityConfig`类,重写WebSecurityConfigurerAdapter,配置Redis作为用户认证存储: ```java @Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Value("${spring.redis.authKey}") private String authKey; @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .defaultSuccessUrl("/") .failureHandler(new CustomAuthenticationFailureHandler()) .and() .logout() .permitAll(); } @Bean public AuthenticationManager authenticationManager() throws Exception { RedisAuthenticationProvider provider = new RedisAuthenticationProvider(); provider.setConnectionFactory(connectionFactory()); provider.setUserDetailsMapper(userDetailsService); return provider; } @Bean public RedisTemplate<String, Object> redisTemplate() { RedisTemplate<String, Object> template = new RedisTemplate<>(); JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setHostName(authKey); //...其他属性配置 template.setConnectionFactory(factory); template.afterPropertiesSet(); return template; } } ``` 4. **用户服务** (`UserDetailsService`实现): 从Redis中读取用户的加密密码并验证: ```java @Service public class UserService implements UserDetailsService { private final JdbcTemplate jdbcTemplate; @Autowired public UserService(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { //从Redis获取用户信息,比如通过username和hash存储 Map<String, Object> userDetails = jedis.get(username); if (userDetails == null) throw new UsernameNotFoundException("Invalid username"); //解码密码并进一步处理... } } ``` 5. **登录和注销**: 使用Spring Security提供的表单登录功能,用户输入用户名和密码后会自动进行验证。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值