java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot cookie session用户登录

SpringBoot  Cookie & Session 用户登录及登录状态保持功能实现代码

作者:q***4986

文章主要内容介绍了会话跟踪技术,包括会话建立、结束、会话跟踪定义以及客户端和服务端会话跟踪技术(如Cookie和Session令牌技术),文章详细描述了Session的使用场景、工作原理、常用方法和认证流程,感兴趣的朋友一起看看吧

会话技术

  1. 功能:提供用户登陆成功后的登陆标记 (一次登录,一段时间都登录)
  2. 会话
    1. 定义:包含一次或多次请求和响应的访问操作
    2. 建立会话:用户打开浏览器访问 Web 服务器资源时建立会话
    3. 结束会话:一方断开连接时结束会话
  3. 会话跟踪
    1. 定义:一种维护浏览器状态的方法
    2. 功能:服务器通过会话跟踪来识别多次请求是否来自于同一浏览器
    3. 同一次会话的多次请求间共享数据
  4. 会话跟踪方案

客户端会话跟踪技术 : Cookie

服务端会话跟踪技术 : Session

令牌技术(token)

令牌 : 用户身份的标识,实际上就是一个字符串

Cookie

  1. 定义:浏览器访问服务器后,服务器传给浏览器的一段数据,由浏览器保存,后续通信中浏览器也要将 Cookie 发送给服务器
  2. 功能
    1. 识别用户身份 (uid)
    2. 存储用户偏好:让浏览器记住这位访客的特定信息
  3. 工作条件
    1. 浏览器每次访问该服务器,都必须带上 Cookie
    2. 浏览器需要保存 Cookie,不得轻易删除
    3. 不能跨域
  4. 工作流程
    1. 客户端提交一个HTTP请求给服务端
    2. 服务端 Set-Cookie,同时提交响应内容给客户端
    3. 客户端再次向服务器请求,并在请求头中携带一个Cookie
  5. 有效期
    1. Expire 值:Cookie 在生成时就会被指定一个 Expire 值,这就是 Cookie 的生存周期
    2. 立即清除 Cookie:生存周期设置为 “0” 或负值,这样在关闭浏览器时,就马上清除 Cookie,不会记录用户信息,更加安全
  6. 缺点
    1. 数量限制:一个浏览器能创建的 Cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的 Cookie 总数不能超过 20 个
    2. 安全性低:存在跨站点脚本攻击的可能,脚本指令可以读取当前站点的所有 Cookie 内容,并且可以提交到指定服务器重现其功能

问:为什么需要 Cookie 答:web程序使用的HTTP协议是无状态的协议,对于事务处理没有记忆能力,如果后续处理需要前面的信息则必须重传,导致每次连接传送的数据量增大

Session

一、概述

  1. 定义
    1. Session (会话控制),Session 对象存储特定用户会话所需的属性及配置信息
    2. SessionID:客户端第一次请求服务器时,服务器为客户端算出的一个值,存储在 Cookie 中,用于定位用户 Session 在服务器中的位置
  2. 与 Cookie 的区别:Cookie 可以通过伪造来实现登录并进行一些 HTTP 请求,从安全性上来讲,Session 比 Cookie 安全性稍微高一些
  3. 功能 :提高安全性
  4. 有效期:一般为半小时,可以根据需求设定
  5. 缺点:Session 是存储在服务器当中的,所以 Session 过多,会对服务器产生压力

二、相关工具类

三、认证流程

工作流程

  1. 创建 Session :用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的 Session
  2. 响应 Session ID:服务器响应请求时,将此 Session 的唯一标识信息 SessionID 返回给浏览器
  3. 存入 Cookie:浏览器接收到服务器返回的 SessionID 信息后,将此信息存入到 Cookie 中,同时 Cookie 记录此 SessionID 属于哪个域名
  4. 携带 Cookie:当用户第二次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息
    1. 存在 Cookie → 自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息
      1. 找到 Session → 证明用户已经登录可执行后面操作
      2. 未找到 Session → 可能是已过期的 Session 或者是假 Cookie
    2. 不存在 Cookie → 说明用户没有登录或者登录失效

原理说明

GET /some/resource HTTP/1.1
Host: www.example.com
Cookie: JSESSIONID=1234567890ABCDEF

四、示例

实现逻辑

示例代码

UserDTO 类(com.projectname.dto.UserDTO)

// com.projectname.dto.UserDTO
@Data
public class UserDTO {
    private Long id;
    private String nickName;
    private String icon;
}

UserHolder 类(com.myproject.utils.UserHolder.java)

// com.projectname.utils.UserHolder
public class UserHolder {
    private static final ThreadLocal<UserDTO> tl = new ThreadLocal<>();
    public static void saveUser(UserDTO user){
        tl.set(user);
    }
    public static UserDTO getUser(){
        return tl.get();
    }
    public static void removeUser(){
        tl.remove();
    }
}
@Component
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 1. 从请求头中获取 Token,如果没有 Token 则跳过拦截器(可能是未登录状态)
    String token = request.getHeader("Authorization");
    if (!StringUtils.hasText(token)) {
        return true;
    }
    // 2. 校验 Token 并解析用户信息(此处简单模拟,实际应调用 Token 验证服务或工具类)
    UserDTO user = validateTokenAndGetUser(token);
    if (user == null) {        // 如果解析失败,允许继续(未登录状态)
        return true;
    }
    // 3. 将用户信息保存到 UserHolder 中
    UserHolder.setUser(user);
    return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    // 请求处理完成后清理 ThreadLocal,防止内存泄漏
    UserHolder.clear();
}
	// 模拟 Token 校验并获取用户信息
private UserDTO validateTokenAndGetUser(String token) {
    // 示例:模拟解析 Token 获取用户
    if ("valid-token".equals(token)) {
        return getUserByToken(token);
    }
    return null; // Token 无效或解析失败
}

}

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private UserInterceptor userInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(userInterceptor)             // 注册拦截器
                .addPathPatterns("/**")                      // 拦截所有路径
                .excludePathPatterns("/login", "/register"); // 排除登录、注册等公开路径
    }
}

到此这篇关于SpringBoot Cookie &amp; Session 用户登录及登录状态保持功能实现代码的文章就介绍到这了,更多相关springboot cookie session用户登录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文