You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于SSO场景,如何在Rails应用中读取Node/Express设置的Cookie?

在Rails应用中读取Node/Express设置的Cookie(共用SSO场景)

我来帮你梳理下在Rails里读取Node/Express设置的Cookie的步骤,尤其是你们共用SSO的场景,关键点在于Cookie的跨域共享配置和Rails端的安全读取:

第一步:确保Node/Express端的Cookie配置支持跨域共享

两个应用要能共享Cookie,首先得让Node端写入的Cookie符合跨域规则,核心配置项如下:

  • Domain:必须设置为两个应用的共同父域名(比如Node应用在app1.example.com,Rails在app2.example.com,那Domain设为.example.com)
  • SameSite:同父域名下用Lax即可;如果是完全跨域且需要HTTPS,可设为None(必须配合Secure)
  • Secure:生产环境开启HTTPS时务必设为true,保证Cookie仅通过HTTPS传输
  • HttpOnly:建议开启,防止前端JS读取Cookie,提升安全性(Rails后端依然可以正常读取)

Node/Express的示例代码:

const jwt = require('jsonwebtoken'); // 后续签名验证用,可选但推荐
const secretKey = process.env.SHARED_SECRET; // 和Rails共用的密钥

// 准备要存入Cookie的用户设置数据
const userSettings = { user_id: 123, preferences: { theme: 'dark' } };

// 推荐对数据签名,防止篡改
const signedToken = jwt.sign(userSettings, secretKey, { expiresIn: '1d' });

// 写入Cookie
res.cookie('sso_user_settings', signedToken, {
  domain: '.example.com',
  secure: process.env.NODE_ENV === 'production',
  sameSite: 'Lax',
  httpOnly: true,
  maxAge: 24 * 60 * 60 * 1000 // 有效期1天
});

第二步:在Rails端读取并验证Cookie

Rails中可以通过cookies对象直接读取Cookie,但为了安全,建议验证Cookie的合法性(比如用JWT签名验证):

1. 基础读取(无签名验证,不推荐生产环境)

def load_user_settings
  # 读取Node端设置的Cookie
  sso_cookie = cookies[:sso_user_settings]
  
  if sso_cookie.present?
    # 解析JSON字符串为Ruby Hash
    user_settings = JSON.parse(sso_cookie)
    # 配置你的业务变量
    @current_user_id = user_settings['user_id']
    @user_preferences = user_settings['preferences']
  else
    # Cookie不存在,跳转回SSO重新认证
    redirect_to sso_login_path
  end
end

2. 安全读取(带JWT签名验证,推荐生产环境)

首先在Gemfile中添加JWT依赖:

gem 'jwt'

执行bundle install后,在控制器中验证:

def load_user_settings
  sso_token = cookies[:sso_user_settings]
  
  if sso_token.present?
    begin
      secret_key = ENV['SHARED_SECRET'] # 和Node端一致的密钥
      # 解码并验证签名、过期时间
      user_settings = JWT.decode(sso_token, secret_key, true, algorithm: 'HS256')[0]
      
      # 配置业务变量
      @current_user_id = user_settings['user_id']
      @user_preferences = user_settings['preferences']
    rescue JWT::DecodeError, JWT::ExpiredSignature
      # 签名无效或过期,重新认证
      redirect_to sso_login_path
    end
  else
    redirect_to sso_login_path
  end
end

第三步:同步Rails会话的域名配置

为了避免Rails会话和SSO Cookie的域名冲突,需要在config/initializers/session_store.rb中设置会话的Domain:

Rails.application.config.session_store :cookie_store, 
  key: '_your_rails_app_session',
  domain: '.example.com' # 和Cookie的Domain保持一致

调试小技巧

  • 用浏览器开发者工具(Application -> Cookies)检查Cookie的Domain、Secure、HttpOnly等属性是否符合预期
  • 在Rails控制台中直接测试读取:cookies[:sso_user_settings]
  • 确认两个应用的HTTPS配置(生产环境),否则Secure Cookie无法写入

内容的提问来源于stack exchange,提问作者Sunny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:37:34