1. 发送验证码

Untitled

@PostMapping("code")
public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {
    // 发送短信验证码并保存验证码
    // 1. 验证手机号
    if (RegexUtils.isPhoneInvalid(phone)) {
        return Result.fail("手机格式不对");
    }
    // 2. 生成验证码
    String code = RandomUtil.randomNumbers(6);
    // 3. 保存验证码
    stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY + phone, code,
			 LOGIN_CODE_TTL, TimeUnit.MINUTES);
    // 4. 发送验证码
    // session.setAttribute("code", phone + "_" + code);
    log.info("验证码发送成功:" + code);
    return Result.ok("生成验证码成功");
}

2. 登陆与注册(Redis存储Hash数据)

@PostMapping("/login")
public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){
    // 实现登录功能
    // 1. 验证验证码
    String phone = loginForm.getPhone();
    String submit_code = loginForm.getCode();

    // Object code = session.getAttribute("code");
    String code = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
    if(code == null || !code.equals(submit_code)) {
        return Result.fail("验证码不正确");
    }
    // 2. 根据手机号进行登陆
    UserDTO user = userService.login(phone);
    // 3. **存储用户到redis里面去**
    String uuid = UUID.randomUUID().toString();
    Map<String, Object> map = BeanUtil.beanToMap(user, new HashMap<>(),
        CopyOptions.create().setIgnoreNullValue(true)
            .setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));
    stringRedisTemplate.opsForHash().putAll(LOGIN_USER_KEY + uuid, map);
    stringRedisTemplate.expire(LOGIN_USER_KEY+ uuid, LOGIN_USER_TTL, TimeUnit.MINUTES);
    // session.setAttribute("user", user);
    return Result.ok(uuid);
}

<aside> 💡 BeanUtil.beanToMap 将Bean转换为一个Map,然后存储到Redis的Hash进去。

</aside>

3. 两个拦截器

Untitled

状态刷新拦截器

public class InterceptorRefresh implements HandlerInterceptor {
    private StringRedisTemplate stringRedisTemplate;

    public InterceptorRefresh(StringRedisTemplate _stringRedisTemplate) {
        this.stringRedisTemplate = _stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 获取请求头的token
        String authorization = request.getHeader("authorization");
        // 2. 如果token为空,直接返回
        if(StrUtil.isBlank(authorization)) {
            return true;
        }
        // 3. 判断用户是否存在
        Map<Object, Object> map = this.stringRedisTemplate.opsForHash().entries(LOGIN_USER_KEY + authorization);
        if(map.isEmpty()) {
            return true;
        }
        // 4. 进行转换
        UserDTO userDTO = BeanUtil.fillBeanWithMap(map, new UserDTO(), false);
        // 5. 登陆存储用户
        UserHolder.saveUser(userDTO);
        // 6. 刷新有效期
        stringRedisTemplate.expire(LOGIN_USER_KEY + authorization, LOGIN_USER_TTL, TimeUnit.MINUTES);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserHolder.removeUser();
    }
}

登陆验证拦截器

public class InterceptorLogin implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(UserHolder.getUser() == null) {
            return false;
        }
        return true;
    }
}

注册拦截器

按照顺序依次拦截

@Configuration
public class MvcConfig implements WebMvcConfigurer {
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new InterceptorRefresh(stringRedisTemplate));
        registry.addInterceptor(new InterceptorLogin())
            .excludePathPatterns(
                "/shop/**",
                "/voucher/**",
                "/shop-type/**",
                "/upload/**",
                "/blog/hot",
                "/user/code",
                "/user/login"
            );
    }
}

4. 获取个人信息

@GetMapping("/me")
public Result me(){
    // 获取当前登录的用户并返回
    UserDTO user = UserHolder.getUser();
    return Result.ok(user);
}