session实现登录以及session与Cookie的关系

基于session实现登录

image.png

发送短信验证码:

image.png

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(phone, code);
    // 5.发送验证码
    log.info("手机验证码:{}", code);
    return Result.ok(code);
}

短信验证码登录、注册:

image.png

public Result login(LoginFormDTO loginForm, HttpSession session) {
    String code = loginForm.getCode();
    String phone = loginForm.getPhone();
    // 1.校验手机号
    if(RegexUtils.isPhoneInvalid(phone)){
        return Result.fail("手机号格式错误");
    }
    // 2.校验验证码
    Object cacheCode = session.getAttribute(phone);
    if(cacheCode == null || !cacheCode.toString().equals(code)){
        // 3.不合法,返回错误信息
        return Result.fail("验证码错误");
    }
    // 4.合法,根据手机号查询用户
    User user = query().eq("phone", phone).one();
    // 5.用户存在,跳过
    // 6.用户不存在
    if(user == null){
        // 6.1 注册
        user = createUserWithPhone(phone);
    }
    // 7 保存到session中
    session.setAttribute("user", user);
    return Result.ok();
}

校验登录状态

校验登录是放在拦截器中的,这样每个业务不用单独再实现校验登录,但是这样会出现线程安全问题,可以用TreadLocal(线程级,tomcat中每个请求都会有一个独立线程)。

image.png

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 1.获取session
    HttpSession session = request.getSession();
    // 2.获取session中的user
    Object user = session.getAttribute("user");
    // 3.判断user是否存在
    if(user == null){
        // 4.不存在,拦截    未授权
        response.setStatus(401);
        return false;
    }
    // 5.存在,保存用户信息到ThreadLocal中
    UserHolder.saveUser((User) user);
    // 6.放行
    return true;
}
​
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    // 移除用户
    UserHolder.removeUser();
}
public class UserHolder {
    private static final ThreadLocal<User> tl = new ThreadLocal<>();
​
    public static void saveUser(User user){
        tl.set(user);
    }
​
    public static User getUser(){
        return tl.get();
    }
​
    public static void removeUser(){
        tl.remove();
    }
}
@Configuration
public class MvcConfig implements WebMvcConfigurer {
​
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
        .excludePathPatterns(
            "/user/code",
            "/user/login",
            "/blog/hot",
            "/shop/**",
            "/shop-type/**",
            "/upload/**",
            "/voucher/**"
        );
    }
}

session与Cookie

Cookie

因为session是基于Cookie的,故先聊聊cookie。 Cookie是由Web服务器发送到用户浏览器并存储在用户计算机的小型数据文件,用来在用户访问网站时存储和发送有关用户信息,帮助网站记住用户的状态和偏好。

session简介

session(域对象),用于一次会话期间保存共享数据的对象。 session是基于Cookie的,用户第一次使用session时(访问页面),服务器会为用户创建一个session域对象,使用jsessionid和session对象关联,以后请求体都会增加:jessionid=xxxx

session管理

  • Cookie:服务器通过设置一个带有jsessionid的cookie发送给客户端。之后的每次请求,浏览器自动附带该cookie,便于服务器识别对应的会话。

  • URL重写:某些情况下,cookie无法使用(被禁用等),jsessionid附加到URL中,格式为URL;jsessionid=xxxx

  • JWT令牌, 一种用于安全传输信息的紧凑的URL安全的令牌格式(头部,负载,签名)。

session的作用

  • Session是为了解决HTTP无状态性问题。

  • session解决Cookie的局限:Cookie过多时,增加了客户端与服务端的数据传输量,而且浏览器对Cookie是有数量限制的,所以我们不能在Cookie中保存过多的信息。

  • session的作用就是在服务器端保存一些用户数据,然后传递给用户一个名为jsessionid的Cookie,一个jsessionid对应一个session对象,通过jsessionid就可以获取到用户的信息

  • 常用于用户身份认证、个性化设置、购物车功能等。

session的安全性

为了保障Session的安全性,防止会话劫持(如Session Fixation攻击),通常会采取以下措施:

  • session ID的随机性和不可预测性: 确保Session ID的生成是随机的,且不可预测。

  • HTTPS: 使用HTTPS加密传输数据,防止session ID在传输过程中被窃取。

  • session固定攻击的防护: 在用户登录后重新生成session ID。

  • session过期时间: 设置合理的session过期时间,防止长期未操作的session被利用。

###

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值