
记得之前做过短信验证的网站,第一次没经验把验证码发送给前端,在前端进行验证,发现并不好,也不是很安全。
第一步: 安装使用Redis,不懂得小伙伴去学习吧,前面有文章介绍可以看下
操作Redis的String第二步: 本文配置Redis (一) 引入依赖
<!--Redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
(二) 配置序列化 要不然会出问题 /**
@author lihaodong
@create 2018-12-01 15:21
@mail lihaodongmail@163.com
@desc **/
@Configuration @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) public class RedisConfig {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
//使用fastjson序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean(StringRedisTemplate.class)
public StringRedisTemplate stringRedisTemplate(
RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
} /**
@author lihaodong
@create 2018-12-01 15:20
@mail lihaodongmail@163.com
@desc **/
public class FastJsonRedisSerializer implements RedisSerializer {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
public FastJsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (null == t) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (null == bytes || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return (T) JSON.parseObject(str, clazz);
}
} 第三步: 配置完Redis,具体业务代码
RedisService
/**
* @author lihaodong
* @create 2018-12-01 15:27
* @mail lihaodongmail@163.com
* @desc
**/
public interface RedisService {
// 保存用户手机验证码
boolean savePhoneCode(String phone, String securityCode, long timeout);
// 通用 通过key获取value
String get(String key);
}
RedisServiceImpl
/**
* @author lihaodong
* @create 2018-12-01 15:32
* @mail lihaodongmail@163.com
* @desc
**/
@Slf4j
@Service
public class RedisServiceImpl implements RedisService {
@Autowired
RedisTemplate redisTemplate;
@Override
public boolean savePhoneCode(String phone, String securityCode, long timeout) {
try {
// 设置的是2分钟失效,2分钟之内查询有结果,2分钟之后返回为null或者空指针
redisTemplate.opsForValue().set(phone, securityCode, timeout, TimeUnit.MINUTES);
return true;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
@Override
public String get(String key) {
try {
return redisTemplate.opsForValue().get(key).toString();
} catch (Exception e){
log.error(e.getMessage());
return null;
}
}
}
controller
// 注册用户的短信行为
@RequestMapping("/sendMessage/{phone}")
public RestResponseBo sendMessage(@PathVariable("phone") String phone) {
Map<String, Object> map = SendMsg.sendSMSG(phone);
// 获取状态码 00000 成功 00141 一小时内发送给单个手机次数超过限制 00142 一天内发送给单个手机次数超过限制
String respCode = map.get("respCode").toString();
String securityCode = map.get("securityCode").toString();
// 短信下发成功 存入redis缓存 有效期2分钟
if (respCode.equals("00000")){
redisService.savePhoneCode(phone,securityCode,2);
} else if (respCode.equals("00141")){
} else if (respCode.equals("00142")){
}
return RestResponseBo.ok(respCode);
}
RestResponseBo 是我封装的一个响应类,自定义类就好或者直接返回Map
状态码是我根据秒滴官网来定义的,省了我们很多代码很方便,不用自定义去判断用户的发送的频率等
@RequestMapping("/check")
public RestResponseBo checkCode(String phone,String code){
String s = redisService.get(phone);
if (s != null){
if (s.equals(code)){
return RestResponseBo.ok(000);
}
return RestResponseBo.fail(101,"验证码错误");
}
return RestResponseBo.fail(102,"验证码已过期,请重新获取");
}
用来判断验证码的 安全问题自己去加




