session 共享

本文介绍了一种使用Memcached作为缓存服务器进行会话管理的方法。通过实现SessionProvider接口,可以将用户的会话数据存储在Memcached中,并提供了设置、获取会话数据以及注销的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**
 * 远程Session
 * 存放在Memcached缓存服务器里的Session
 * @author lx
 *
 */
public class CacheSessionProvider implements SessionProvider {
    @Autowired
    private MemCachedClient  memCachedClient;
    private final String SESSIONID="sessionId";
    //设置数据保存在memcached的保存时间
    private final Integer  expiry=30*60;

    /**
     * 将session的值通过sessionId值存入memcached中
     */
    public void setAttribute(HttpServletRequest request, String name, Serializable value,HttpServletResponse response) {
        // TODO Auto-generated method stub
        Map<String, Serializable> session=new HashMap<String, Serializable>();
        session.put(name, value);
        String sessionId=getSessionId(request, response);
        memCachedClient.set(sessionId, session, expiry);
    }
/**
 * 通过用户本地的sessionId值到服务器获取session
 * 从缓存服务器memcached中获取sessionId值对应的session
 */
    public Serializable getAttribute(HttpServletRequest request, String name,HttpServletResponse response) {
        // TODO Auto-generated method stub
        String sessionId=getSessionId(request, response);
        Map<String, Serializable> session = (Map<String, Serializable>)memCachedClient.get(sessionId);
        //返回保存在session中的用户数据
        if(session!=null){
            return session.get(name);
        }
        return null;
    }
    /**
     * 
     * 删除缓存服务器memcached中中key=sessionId,这样用户即使
     * 通过本地的sessionID也获取不到用户的数据
     */
    public void logout(HttpServletRequest request,HttpServletResponse response) {
        // TODO Auto-generated method stub
        //用户本地cookie
        String sessionId=getSessionId(request, response);
        if(memCachedClient.keyExists(sessionId)){
            memCachedClient.delete(sessionId);
        }

    }
/**
 * 获取sessionId,如果用户没有sessionId,则为用户创建一个sessionId
 */
    public String getSessionId(HttpServletRequest request,HttpServletResponse response) {
        //获取存储在cookie的sessionId
           Cookie[] cookies = request.getCookies();
           if(cookies!=null && cookies.length>0){
               for (Cookie cookie : cookies) {
                   if(SESSIONID.equals(cookie.getName())){
                       return cookie.getValue();
                   }
            }
           }
           //如果没有sessionId,为用户创建一个
           String sessionId=UUID.randomUUID().toString().replaceAll("-", "");
           Cookie cookie=new Cookie(SESSIONID, sessionId);
           cookie.setMaxAge(-1);// 默认-1,代表关闭浏览器就销毁cookie
           cookie.setPath("/");
           response.addCookie(cookie);
        return sessionId;
    }

转载于:https://www.cnblogs.com/feiZhou/p/9344195.html

<think>嗯,用户想了解如何在不同环境或应用中实现Session共享,特别是跨域的解决方案。我之前整理过几个引用,里面提到了Cookie的Domain设置、自定义Session ID、集中存储这些方法。需要先理清楚这些方法的适用场景和步骤。 首先,Cookie的Domain属性设置,比如将Domain设为.example.com,这样所有子域都能共享Session。但用户可能还涉及完全不同的域,这时候可能需要其他方法。比如引用3里提到自定义Session ID,存储在服务端,如数据库或Redis,这样不同的域都能通过这个ID来获取Session数据。然后,集中存储方案,比如Redis或数据库,这适用于不同服务器之间共享Session。需要确保所有应用服务器都连接同一个存储,这样无论请求到哪台服务器,都能访问到相同的Session数据。这可能和负载均衡有关,比如引用里提到的Nginx配置,但用户的问题更偏向Session共享而不是负载均衡。还有SSO单点登录,这属于更高级的解决方案,可能涉及独立的认证中心,比如OAuth或JWT。这时候每个应用向认证中心验证token,实现跨域登录。这可能适合用户提到的不同应用间的共享,但需要更复杂的设置。 另外,用户可能关心的是具体实现步骤,比如代码示例。例如PHP设置Cookie的Domain,或者Java中配置SpringSession使用Redis。需要分点说明不同的方法,并给出对应的技术实现,比如代码片段或配置示例。 还要注意安全性,比如Cookie的Secure和HttpOnly属性,SameSite设置,防止CSRF攻击。引用里提到Secure:true和SameSite: None,这些在HTTPS下是必要的。可能还需要比较这些方法的优缺点。比如Cookie跨子域简单,但无法跨完全不同的域;集中存储需要基础设施支持;SSO适合大型系统但实现复杂。用户可能需要根据他们的具体场景选择合适的方法。最后,生成相关问题,帮助用户进一步探索。比如如何确保Session共享的安全性,或者微服务架构下的Session管理。这些问题可以引导用户深入思考他们的需求。</think>### 跨域Session共享解决方案 #### 一、基于Cookie的跨域共享(同主域场景) 1. **适用场景** 系统运行在相同主域下的子域(如`a.example.com`和`b.example.com`),通过设置Cookie的`Domain`属性实现共享: ```go http.SetCookie(w, &http.Cookie{ Name: "SESSION_ID", Value: "your-session-id", Domain: ".example.com", // 允许所有子域共享 Path: "/", HttpOnly: true, Secure: true, // 仅HTTPS生效 SameSite: http.SameSiteNoneMode, }) ``` - **原理**:浏览器会自动将Cookie发送到匹配域名的请求中[^1][^2]。 - **限制**:仅适用于同一主域下的跨子域场景。 --- #### 二、自定义Session ID + 集中存储(跨域通用) 1. **实现步骤** - **生成全局Session ID**:用户登录时生成唯一标识(如UUID),存入跨域Cookie。 - **集中存储Session数据**:将数据保存到Redis或数据库,例如: ```php setcookie("session_idx", $session_id, time()+3600*24*365*10, "/", ".example.com"); Redis::set("session:$session_id", serialize($user_data)); ``` - **跨域验证**:不同域的应用通过Session ID查询集中存储获取用户状态[^3][^4]。 2. **技术选型** - **存储层**:Redis(高性能)、MySQL(强一致性)。 - **框架支持**:Spring Session(Java)、Flask-Session(Python)。 --- #### 三、基于Token的无状态方案(完全跨域) 1. **JWT(JSON Web Token)** - **流程**:用户登录后返回加密Token,包含用户信息,由客户端存储并在跨域请求中携带。 - **示例Token结构**: ```json { "sub": "user123", "exp": 1625145600, "domain_a": "read", "domain_b": "write" } ``` - **优点**:无需服务端存储Session,天然支持跨域[^3]。 --- #### 四、反向代理统一域名(简化跨域) 1. **Nginx配置** 通过反向代理将不同域名的请求映射到统一入口: ```nginx server { server_name sso.example.com; location / { proxy_pass http://backend-server; proxy_set_header Host $host; } } ``` - **效果**:所有应用通过`sso.example.com`共享Session,规避浏览器跨域限制。 --- #### 五、单点登录(SSO)系统 1. **核心组件** - **认证中心**:独立服务处理登录/注销。 - **Ticket验证**:通过重定向传递临时票据(如CAS协议)。 - **跨域Cookie联动**:使用隐藏iframe或前端存储同步登录状态。 --- ### 对比分析 | 方案 | 适用场景 | 复杂度 | 安全性要求 | |---------------------|--------------------------|--------|--------------------| | Cookie Domain | 同主域的子域 | 低 | 中(需HTTPS) | | 集中存储 + Session ID | 任意跨域 | 中 | 高(需加密存储) | | JWT | 无状态API跨域 | 中 | 高(密钥管理) | | SSO | 多系统统一认证 | 高 | 极高(防重放攻击) | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值