暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Redis实现短信验证码验证

小东IT技术分享 2018-12-04
1423

记得之前做过短信验证的网站,第一次没经验把验证码发送给前端,在前端进行验证,发现并不好,也不是很安全。

第一步: 安装使用Redis,不懂得小伙伴去学习吧,前面有文章介绍可以看下

Redis安装

操作Redis的String第二步: 本文配置Redis (一) 引入依赖

  1.    <!--Redis依赖-->

  2.    <dependency>

  3.        <groupId>org.springframework.boot</groupId>

  4.        <artifactId>spring-boot-starter-data-redis</artifactId>

  5.    </dependency>

(二) 配置序列化 要不然会出问题 /**

  • @author lihaodong

  • @create 2018-12-01 15:21

  • @mail lihaodongmail@163.com

  • @desc **/

@Configuration @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) public class RedisConfig {

  1. @Bean

  2. @ConditionalOnMissingBean(name = "redisTemplate")

  3. public RedisTemplate<Object, Object> redisTemplate(

  4.        RedisConnectionFactory redisConnectionFactory) {

  5.    RedisTemplate<Object, Object> template = new RedisTemplate<>();



  6.    //使用fastjson序列化

  7.    FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);

  8.    // value值的序列化采用fastJsonRedisSerializer

  9.    template.setValueSerializer(fastJsonRedisSerializer);

  10.    template.setHashValueSerializer(fastJsonRedisSerializer);

  11.    // key的序列化采用StringRedisSerializer

  12.    template.setKeySerializer(new StringRedisSerializer());

  13.    template.setHashKeySerializer(new StringRedisSerializer());



  14.    template.setConnectionFactory(redisConnectionFactory);

  15.    return template;

  16. }



  17. @Bean

  18. @ConditionalOnMissingBean(StringRedisTemplate.class)

  19. public StringRedisTemplate stringRedisTemplate(

  20.        RedisConnectionFactory redisConnectionFactory) {

  21.    StringRedisTemplate template = new StringRedisTemplate();

  22.    template.setConnectionFactory(redisConnectionFactory);

  23.    return template;

  24. }

} /**

  • @author lihaodong

  • @create 2018-12-01 15:20

  • @mail lihaodongmail@163.com

  • @desc **/

public class FastJsonRedisSerializer implements RedisSerializer {

  1. public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");



  2. private Class<T> clazz;



  3. public FastJsonRedisSerializer(Class<T> clazz) {

  4.    super();

  5.    this.clazz = clazz;

  6. }



  7. @Override

  8. public byte[] serialize(T t) throws SerializationException {

  9.    if (null == t) {

  10.        return new byte[0];

  11.    }

  12.    return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);

  13. }



  14. @Override

  15. public T deserialize(byte[] bytes) throws SerializationException {

  16.    if (null == bytes || bytes.length <= 0) {

  17.        return null;

  18.    }

  19.    String str = new String(bytes, DEFAULT_CHARSET);

  20.    return (T) JSON.parseObject(str, clazz);

  21. }

} 第三步: 配置完Redis,具体业务代码

RedisService

  1. /**

  2. * @author lihaodong

  3. * @create 2018-12-01 15:27

  4. * @mail lihaodongmail@163.com

  5. * @desc

  6. **/

  7. public interface RedisService {



  8.    // 保存用户手机验证码

  9.    boolean savePhoneCode(String phone, String securityCode, long timeout);

  10.    // 通用 通过key获取value

  11.    String get(String key);

  12. }

RedisServiceImpl

  1. /**

  2. * @author lihaodong

  3. * @create 2018-12-01 15:32

  4. * @mail lihaodongmail@163.com

  5. * @desc

  6. **/

  7. @Slf4j

  8. @Service

  9. public class RedisServiceImpl implements RedisService {



  10.    @Autowired

  11.    RedisTemplate redisTemplate;



  12.    @Override

  13.    public boolean savePhoneCode(String phone, String securityCode, long timeout) {

  14.        try {

  15.            // 设置的是2分钟失效,2分钟之内查询有结果,2分钟之后返回为null或者空指针

  16.            redisTemplate.opsForValue().set(phone, securityCode, timeout, TimeUnit.MINUTES);

  17.            return true;

  18.        } catch (Exception e) {

  19.            log.error(e.getMessage());

  20.            return false;

  21.        }

  22.    }



  23.    @Override

  24.    public String get(String key) {

  25.        try {

  26.            return redisTemplate.opsForValue().get(key).toString();

  27.        } catch (Exception e){

  28.            log.error(e.getMessage());

  29.            return null;

  30.        }



  31.    }

  32. }

controller

  1. // 注册用户的短信行为

  2.    @RequestMapping("/sendMessage/{phone}")

  3.    public RestResponseBo sendMessage(@PathVariable("phone") String phone) {

  4.        Map<String, Object> map = SendMsg.sendSMSG(phone);

  5.        // 获取状态码 00000 成功 00141 一小时内发送给单个手机次数超过限制 00142 一天内发送给单个手机次数超过限制

  6.        String respCode = map.get("respCode").toString();

  7.        String securityCode = map.get("securityCode").toString();

  8.        // 短信下发成功 存入redis缓存 有效期2分钟

  9.        if (respCode.equals("00000")){

  10.            redisService.savePhoneCode(phone,securityCode,2);

  11.        } else if (respCode.equals("00141")){



  12.        } else if (respCode.equals("00142")){



  13.        }

  14.        return RestResponseBo.ok(respCode);

  15.    }

  16. RestResponseBo 是我封装的一个响应类,自定义类就好或者直接返回Map



  17. 状态码是我根据秒滴官网来定义的,省了我们很多代码很方便,不用自定义去判断用户的发送的频率等



  18. @RequestMapping("/check")

  19.    public RestResponseBo checkCode(String phone,String code){

  20.        String s = redisService.get(phone);

  21.        if (s != null){

  22.            if (s.equals(code)){

  23.                return RestResponseBo.ok(000);

  24.            }

  25.            return RestResponseBo.fail(101,"验证码错误");

  26.        }

  27.        return RestResponseBo.fail(102,"验证码已过期,请重新获取");



  28.    }

用来判断验证码的 安全问题自己去加


文章转载自小东IT技术分享,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论