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

Rails集成Facebook后刷新页面触发CSRF检测错误求助

Fixing OmniAuth CSRF Detected Error in Rails Facebook Integration

Let's break down why you're hitting this CSRF error and how to fix it—your current attempts are targeting Rails' built-in CSRF protection, but the issue is actually coming from OmniAuth's own security checks, plus how you're handling the Facebook token in your edit action.

First, Why Your Previous Tries Didn't Work

  • The skip_before_action :verify_authenticity_token methods affect Rails' form CSRF validation, but your error is from OmniAuth's OAuth2 state verification—so these won't fix the core issue.
  • The authenticate_user/authenticate_user! errors happen because your controller doesn't have those callback methods defined (likely you don't use Devise or a custom auth setup with those names), so those steps are irrelevant here.

Step-by-Step Fixes

1. Ensure OmniAuth is Configured Correctly

First, check your OmniAuth initializer (usually config/initializers/omniauth.rb). Make sure you don't disable state validation—this is critical for OmniAuth's CSRF protection:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :facebook, ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET'],
    scope: 'email,public_profile', # Adjust scopes to match your needs
    provider_ignores_state: false # Leave this as false—disabling it bypasses CSRF checks (not recommended)
end

2. Use Stored Access Tokens in the edit Action

The CSRF error on refresh probably occurs because your edit action is re-triggering an OAuth flow instead of using the access token you already obtained during initial login.

First, store the Facebook access token when the user authenticates (in your OmniAuth callback action):

def facebook_callback
  auth = request.env['omniauth.auth']
  user = User.find_or_create_by(facebook_uid: auth.uid) do |u|
    u.email = auth.info.email
    u.facebook_access_token = auth.credentials.token
  end
  session[:user_id] = user.id # Use Devise's `sign_in(user)` if you're using Devise
  redirect_to edit_employee_path(user.employee), notice: "Successfully connected to Facebook!"
end

Then in your EmployeesController#edit, use this stored token to call the Graph API—don't re-initiate OAuth here:

def edit
  @employee = Employee.find(params[:id])
  # Use the pre-stored token from your user model
  @graph = Koala::Facebook::API.new(current_user.facebook_access_token)
  @facebook_data = @graph.get_object('me', fields: 'name,email,work') # Adjust fields as needed
end

3. Always Redirect from the OAuth Callback

Make sure your OAuth callback action redirects to another page (like edit_employee_path) instead of rendering a view directly. If you render the edit view from the callback, refreshing the page will re-send the OAuth callback request, which fails the state check (since state tokens are one-time use).

4. Add CSRF Tokens to Forms in the Edit View

If your edit page has a form that submits via POST/PUT/PATCH, ensure it includes Rails' CSRF token (this fixes Rails-side CSRF issues, not OmniAuth's, but it's essential for security):

<%= form_with(model: @employee) do |form| %>
  <%# Rails automatically adds the CSRF token in form_with, but you can include it explicitly if needed: %>
  <%= form.authenticity_token %>
  
  <!-- Your form fields here -->
<% end %>

Final Checks

  • Clear your browser session/cookies and test again—stale state tokens can cause unexpected errors.
  • Verify that the facebook_access_token is stored correctly in your user model (check your database to confirm the token exists after authentication).

内容的提问来源于stack exchange,提问作者NIkhil D Anand

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:18:38