Rails API用户认证可接收React代理请求 直接调用时返回未授权
问题根因
你遇到的是跨域场景下Cookie未正确传递的典型问题,开发阶段React代理将前后端请求伪装为同源,浏览器自动携带会话Cookie,因此认证逻辑正常运行。生产/直接调用时前后端分属不同源,fetch默认不携带第三方Cookie,Rails无法读取session信息导致认证失败。
修复步骤
1. 调整前端所有fetch请求配置
所有接口调用(包括登录、登出、CRUD请求)都需要添加credentials: 'include'配置,告知浏览器允许跨域请求携带Cookie,修改后的登录请求示例:
function signin(username, password) { setIsLoading(true); fetch("http://localhost:3000/login", { method: "POST", credentials: "include", // 新增配置 headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username, password }), }).then((r) => { setIsLoading(false); if (r.ok) { r.json().then((user) => { setUser(user); }); } else { r.json().then((err) => setErrors(err.errors)); } }); }
所有其他fetch请求都需要同步添加该配置。
2. 配置Rails跨域规则
确保你已经安装rack-cors gem,修改config/initializers/cors.rb,不要使用通配符*作为允许的源,需明确指定前端域名,同时开启凭证支持:
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '你的生产前端域名', 'http://localhost:3001' # 替换为实际前端地址,多个地址用逗号分隔 resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true # 必须开启,允许跨域携带Cookie end end
3. 调整Session Cookie配置
修改config/initializers/session_store.rb,适配跨域场景的Cookie属性:
Rails.application.config.session_store :cookie_store, key: '_你的应用名_session', same_site: :none, # 跨域场景必须设置为none secure: Rails.env.production? # 生产环境HTTPS下必须开启secure属性
4. 修复Sessions Controller的登出逻辑
你当前的destroy方法存在语法错误,head = :no_content是变量赋值而非返回无内容响应,修改为:
def destroy session.delete(:user_id) head :no_content # 移除赋值等号 end
验证方式
修改完成后重启Rails服务,登录后在浏览器开发者工具的「应用-存储-Cookie」中查看是否存在Rails生成的会话Cookie,后续接口请求的请求头中是否携带该Cookie,即可确认配置生效。
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

