0
点赞
收藏
分享

微信扫一扫

【提高篇】3.1 GPIO(一,基础知识)

墨春 2024-11-13 阅读 18

1.基于Session实现登录

流程图

1.发送验证码

    public Result sendCode(String phone, HttpSession session) {
        //1.校验手机号
        if(RegexUtils.isPhoneInvalid(phone)){
            //2.不符合则返回错误信息
            return Result.fail("手机号格式不正确");
        }
        //3.符合则生成短信验证码
        String code = RandomUtil.randomNumbers(6);
        //4.保存到session中
        session.setAttribute("code",code);
        //5.返送验证码
        log.info("返回验证码是"+code);
        //6.返回信息Ok
        return Result.ok();
    }

正则表达式检验各种格式是否正确

public abstract class RegexPatterns {
    /**
     * 手机号正则
     */
    public static final String PHONE_REGEX = "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";
    /**
     * 邮箱正则
     */
    public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
    /**
     * 密码正则。4~32位的字母、数字、下划线
     */
    public static final String PASSWORD_REGEX = "^\\w{4,32}$";
    /**
     * 验证码正则, 6位数字或字母
     */
    public static final String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$";

}

检验工具类

public class RegexUtils {
    /**
     * 是否是无效手机格式
     * @param phone 要校验的手机号
     * @return true:符合,false:不符合
     */
    public static boolean isPhoneInvalid(String phone){
        return mismatch(phone, RegexPatterns.PHONE_REGEX);
    }
    /**
     * 是否是无效邮箱格式
     * @param email 要校验的邮箱
     * @return true:符合,false:不符合
     */
    public static boolean isEmailInvalid(String email){
        return mismatch(email, RegexPatterns.EMAIL_REGEX);
    }

    /**
     * 是否是无效验证码格式
     * @param code 要校验的验证码
     * @return true:符合,false:不符合
     */
    public static boolean isCodeInvalid(String code){
        return mismatch(code, RegexPatterns.VERIFY_CODE_REGEX);
    }

    // 校验是否不符合正则格式
    private static boolean mismatch(String str, String regex){
        if (StrUtil.isBlank(str)) {
            return true;
        }
        return !str.matches(regex);
    }
}

2.短信验证码登录注册

    public Result login(LoginFormDTO loginForm, HttpSession session) {
        //1.校验手机号
        String phone = loginForm.getPhone();
        if(RegexUtils.isPhoneInvalid(phone)){
            //2.不符合则返回错误信息
            return Result.fail("手机号格式不正确");
        }
        //2.校验验证码
        Object code = session.getAttribute("code");
        String cachecode = loginForm.getCode();
        if(code==null||!code.toString().equals(cachecode)){
            //3.不符合,返回错误信息
            return Result.fail("验证码不一致!");
        }
        //4.符合,根据手机号查询信息
        User user = query().eq("phone", phone).one();
        //5.用户不存在,则创建新用户
        if(user==null){
            user=createUserWithPhone(phone);
        }
        //6.保存用户信息到session中
        session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));
        return Result.ok();
    }

    private User createUserWithPhone(String phone) {
        User user=new User();
        user.setPhone(phone);
        user.setNickName(USER_NICK_NAME_PREFIX+RandomUtil.randomString(10));
        //保存用户
        save(user);
        return user;
    }

3.检验登录状态

public class Logininterception implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取sesssion
        HttpSession session = request.getSession();
        //判断用户是否存在
        Object user = session.getAttribute("user");
        //若无,则结束,返回401未授权
        if(user==null){
            response.setStatus(401);
            return false;
        }
        //有用户信息,则保存用户到threadlocal中
        UserHolder.saveUser((UserDTO) user);
        //放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

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

2.基于Redis实现登录

多台服务器无法共享session,因此使用redis实现登录功能。

1.发送验证码

    public Result sendCode(String phone, HttpSession session) {
        //1.校验手机号
        if(RegexUtils.isPhoneInvalid(phone)){
            //2.不符合则返回错误信息
            return Result.fail("手机号格式不正确");
        }
        //3.符合则生成短信验证码
        String code = RandomUtil.randomNumbers(6);
        //4.保存到redis中
        stringRedisTemplate.opsForValue().set(LOGIN_CODE_KEY+phone,code,2, TimeUnit.MINUTES);
        //5.返送验证码
        log.info("返回验证码是"+code);
        //6.返回信息Ok
        return Result.ok();
    }

2.短信验证码登录注册

    public Result login(LoginFormDTO loginForm, HttpSession session) {
        //1.校验手机号
        String phone = loginForm.getPhone();
        if(RegexUtils.isPhoneInvalid(phone)){
            //2.不符合则返回错误信息
            return Result.fail("手机号格式不正确");
        }
        //2.校验验证码
        String code = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + phone);
        String cachecode = loginForm.getCode();
        if(code==null||!code.equals(cachecode)){
            //3.不符合,返回错误信息
            return Result.fail("验证码不一致!");
        }
        //4.符合,根据手机号查询信息
        User user = query().eq("phone", phone).one();
        //5.用户不存在,则创建新用户
        if(user==null){
            user=createUserWithPhone(phone);
        }
        //6.保存用户信息到redis中
        String token = UUID.randomUUID().toString(true);
        UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
        Map<String, Object> map = BeanUtil.beanToMap(userDTO,new HashMap<>(),
                CopyOptions.create()
                        .setIgnoreNullValue(true)
                        .setFieldValueEditor((filedName,filedValue)->filedValue.toString()));
        String key= LOGIN_USER_KEY+token;
        stringRedisTemplate.opsForHash().putAll(key,map);
        stringRedisTemplate.expire(token,LOGIN_USER_TTL,TimeUnit.MINUTES);
        return Result.ok(token);
    }

    private User createUserWithPhone(String phone) {
        User user=new User();
        user.setPhone(phone);
        user.setNickName(USER_NICK_NAME_PREFIX+RandomUtil.randomString(10));
        //保存用户
        save(user);
        return user;
    }

3.检验登录状态

    private StringRedisTemplate stringRedisTemplate;

    public Logininterception(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取redis
        String token = request.getHeader("authorization");
        if (StrUtil.isBlank(token)) {
            response.setStatus(401);
            return false;
        }
        //判断用户是否存在
        Map<Object, Object> map = stringRedisTemplate.opsForHash().entries(LOGIN_USER_KEY+token);
        //若无,则结束,返回401未授权
        if(map.isEmpty()){
            response.setStatus(401);
            return false;
        }
        UserDTO userDTO = BeanUtil.fillBeanWithMap(map, new UserDTO(), false);
        //有用户信息,则保存用户到threadlocal中
        UserHolder.saveUser(userDTO);
        //刷新有效期
        stringRedisTemplate.expire(LOGIN_USER_KEY+token,LOGIN_USER_TTL, TimeUnit.MINUTES);
        //放行
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

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

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Logininterception(stringRedisTemplate))
                .excludePathPatterns(
                        "/user/code",
                        "/user/login",
                        "/shop/**",
                        "/voucher/**",
                        "/shop-type/**",
                        "/upload/**",
                        "/blog/hot"
                );
    }
}

PS:

在拦截器中不适合@autowird,因为拦截器使我们自己new出来的,不归spring容器管理。

可以使用构造函数注入,因为注册拦截器的类是归spring管理的,所以可以使用@Autowird,将

stringRedisTemplate注入。

举报

相关推荐

0 条评论