Rails 7 API对接React Native时Omniauth认证触发InvalidAuthenticityToken错误
解决Rails 7 API对接React Native Google OAuth2时的InvalidAuthenticityToken错误
问题分析
Web端使用OmniAuth Google OAuth2验证正常,但React Native移动端触发ActionController::InvalidAuthenticityToken,核心原因在于:
- Rails的CSRF保护依赖会话(session),但React Native作为客户端无法像浏览器那样自动获取并传递CSRF令牌
omniauth-rails_csrf_protectiongem默认对所有OmniAuth请求做CSRF验证,而无状态的API场景不适用该验证逻辑
解决方案
1. 在OmniAuth回调控制器中跳过CSRF验证
修改Users::OmniauthCallbacksController,针对API请求跳过CSRF检查,同时保留Web端的CSRF保护:
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController skip_before_action :verify_authenticity_token, if: -> { request.format.json? } def google_oauth2 # 你的Google OAuth2回调处理逻辑 end def failure # 验证失败的处理逻辑 end end
2. 调整OmniAuth的CSRF验证策略
如果需要全局适配API场景,可修改OmniAuth的验证阶段,仅对Web请求保留CSRF验证:
在config/initializers/devise.rb中添加:
OmniAuth.config.request_validation_phase = Proc.new do |env| request = ActionDispatch::Request.new(env) # 仅对非JSON格式的请求执行默认CSRF验证 unless request.format.json? OmniAuth::RailsCsrfProtection.default_request_validation_phase.call(env) end end
3. 确认Rack CORS配置正确
确保config/initializers/cors.rb允许React Native客户端的跨域请求,支持必要的头信息:
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins '你的React Native客户端地址' # 比如开发环境的'exp://192.168.1.100:8081'或生产域名 resource '*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end end
4. 检查React Native端的参数传递
确保客户端传递的令牌参数名符合OmniAuth-google-oauth2的要求,使用下划线命名的id_token而非驼峰式的idToken:
// React Native请求示例 fetch('https://你的Rails API域名/users/auth/google_oauth2/callback', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ id_token: '从Google身份验证获取的令牌' }) })
内容的提问来源于stack exchange,提问作者James Hibbeard
相关产品推荐
相关产品推荐

