Redis 字符串(String)
Redis 字符串数据类型的相关命令用于管理 redis 字符串值。
下表列出了常用的 redis 字符串命令:
序号 | 命令及描述 |
---|---|
1 | SET key value 设置指定 key 的值。 |
2 | GET key 获取指定 key 的值。 |
3 | GETRANGE key start end 返回 key 中字符串值的子字符 |
4 | GETSET key value 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
5 | GETBIT key offset 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。 |
6 | [MGET key1 key2…] 获取所有(一个或多个)给定 key 的值。 |
7 | SETBIT key offset value 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 |
8 | SETEX key seconds value 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
9 | SETNX key value 只有在 key 不存在时设置 key 的值。 |
10 | SETRANGE key offset value 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。 |
11 | STRLEN key 返回 key 所储存的字符串值的长度。 |
12 | [MSET key value key value …] 同时设置一个或多个 key-value 对。 |
13 | [MSETNX key value key value …] 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 |
14 | PSETEX key milliseconds value 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 |
15 | INCR key 将 key 中储存的数字值增一。 |
16 | INCRBY key increment 将 key 所储存的值加上给定的增量值(increment) 。 |
17 | INCRBYFLOAT key increment 将 key 所储存的值加上给定的浮点增量值(increment) 。 |
18 | DECR key 将 key 中储存的数字值减一。 |
19 | DECRBY key decrement key 所储存的值减去给定的减量值(decrement) 。 |
20 | APPEND key value 如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。 |
场景描述
Redis实现短信验证码单点登录
实现思路
验证手机号,将验证码存放于redis中添加过期时间,并持久化于mysql中,登录成功后将用户唯一token存放于redis中,当异地登录时先判断用户本地是否有该token,没有则更新token。
代码实现
发送验证码功能
controller层
@RestController
@RequestMapping("/api/v1/user")
public class UserController {
@Resource
private UserIService userService;
@PostMapping("/SendCode")
public Result SendCode(@RequestBody UserDto userDto){
return userService.SendCode(userDto);
}
}
service层
public Result SendCode(UserDto userDto) {
//随机生成6位手机验证码
String code = generateSixDigitCode();
//用正则表达式验证手机格式是否正确
if(!isValidPhoneNumber(userDto.getPhone())){
return Result.error("手机号格式不对");
}
//存放验证码信息--并且设置60秒的过期时间
cacheService.setEx(UserEnum.TOKEN+userDto.getPhone(),code,60,TimeUnit.SECONDS);
//TODO:这里不调用发送验证码接口
return Result.success();
}
测试用例
POST http://localhost:18888/api/v1/user/login
Content-Type:application/json
{
"phone": "13666667878",
"token": "",
"code": ""
}
结果
登录功能
controller层
@PostMapping("/login")
public Result<UserDto> login(@RequestBody UserDto userDto){
return userService.login(userDto);
}
service层
/**
* 登录功能
* @param userDto
* @return
*/
@Override
public Result<UserDto> login(UserDto userDto) {
//校验手机号
if(!isValidPhoneNumber(userDto.getPhone())){
return Result.error("手机号格式不正确");
}
if(StringUtils.isEmpty(userDto.getCode())){
return Result.error("请填写验证码");
}
//查出来的code为过期
String code = cacheService.get(UserEnum.TOKEN + userDto.getPhone());
if(StringUtils.isEmpty(code)){
return Result.error("验证码过期");
}
if(!code.equals(userDto.getCode())){
return Result.error("验证码不正确");
}
//生成随机token
String token = userDto.getPhone()+":"+new Date();
cacheService.set(UserEnum.User_token+userDto.getPhone(),token);
userDto.setToken(token);
return Result.success(userDto);
}
测试用例
POST http://localhost:18888/api/v1/user/login
Content-Type:application/json
{
"phone": "13666667878",
"token": "",
"code": "647149"
}
结果
异地登录
当本地token与远程token不一致时,及证明远程登录情况发生,则强制本地下线。
controller层
@PostMapping("/Reback")
public Result Reback(@RequestBody UserDto userDto){
return userService.Reback(userDto);
}
service层
/**
* 下线在线用户
* @param userDto
* @return
*/
@Override
public Result Reback(UserDto userDto) {
cacheService.set(UserEnum.User_token+userDto.getPhone()," ");
return Result.success();
}
测试用例
POST http://localhost:18888/api/v1/user/Reback
Content-Type:application/json
{
"phone": "13666667878",
"token": "",
"code": "370522"
}