Rails集成Facebook后刷新页面触发CSRF检测错误求助
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_tokenmethods 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_tokenis stored correctly in your user model (check your database to confirm the token exists after authentication).
内容的提问来源于stack exchange,提问作者NIkhil D Anand

