Rails+React集成Omniauth(Shopify策略)遭遇CORS问题
Hey there, let's walk through what's going on with your Shopify Omniauth setup in your Rails + React app, and how to get the full auth flow working smoothly.
First, let's recap what you've implemented so far:
Your SessionsController Authenticate Action
class SessionsController < ApplicationController def authenticate redirect_to "/auth/shopify?shop=#{params[:shop]}" end end
Current Behavior & Rails Logs
Your browser gets a 302 redirect from Omniauth, and your Rails server logs show:
(shopify) Setup endpoint detected, running now. (shopify) Request phase initiated. 127.0.0.1 - - [29/Mar/2018:15:02:40 DST] "GET /auth/shopify?shop=xxx.myshopify.com HTTP/1.1" 302 280 http://localhost:8082...
First, Relax: That 302 is Expected!
That 302 redirect isn't an error—it's exactly how Omniauth's Shopify strategy kicks off the OAuth flow. Here's the breakdown:
- When your app hits
/auth/shopify, Omniauth is redirecting the user to Shopify's official authorization page, where the merchant will log in and grant your app permissions. - The logs confirming "Request phase initiated" mean your initial setup is working correctly up to this point.
Next Steps: Complete the Callback Flow
To finish the authentication process, you need to handle Shopify's response once the merchant approves (or denies) access. Here's what to do:
1. Configure Shopify App Callback URL
Head to your Shopify Partner Dashboard, find your app, and add your Rails app's callback URL to the Allowed redirection URL(s) field. It should look something like:http://localhost:3000/auth/shopify/callback (adjust the port to match your Rails server).
2. Add a Callback Controller
Create an OmniauthCallbacksController (or extend your SessionsController) to handle Shopify's response:
class OmniauthCallbacksController < ApplicationController def shopify # Pull the authenticated shop/user data from Omniauth auth_data = request.env['omniauth.auth'] # Here, you'd create or find a Shop/User record in your database # Example: @shop = Shop.find_or_create_by(shopify_domain: auth_data[:info][:shop_name]) # Generate a secure token (like JWT) to pass to your React app auth_token = generate_secure_token(@shop) # Redirect back to your React app with the token redirect_to "http://localhost:8082/auth/success?token=#{auth_token}" end def failure # Handle cases where the merchant denied access redirect_to "http://localhost:8082/auth/failure" end end
3. Update Your Routes
Map the callback endpoints in config/routes.rb:
Rails.application.routes.draw do get '/auth/shopify/callback', to: 'omniauth_callbacks#shopify' get '/auth/failure', to: 'omniauth_callbacks#failure' # Your other existing routes... end
4. Double-Check Omniauth Initializer
Make sure your config/initializers/omniauth.rb has the correct credentials and scopes:
Rails.application.config.middleware.use OmniAuth::Builder do provider :shopify, ENV['SHOPIFY_API_KEY'], ENV['SHOPIFY_API_SECRET'], scope: 'read_products,write_orders', # Adjust scopes to match your app's needs embedded_app: true # Set this if you're building an embedded Shopify app end
Common Gotchas to Avoid
- CORS Issues: Since your React app runs on
localhost:8082and Rails on a different port, use therack-corsgem to configure CORS in Rails and allow requests from your React domain. - Secure Token Handling: Avoid passing sensitive data in URLs—use a signed JWT token instead to authenticate the user in your React app.
- Shopify App Scopes: Make sure the scopes in your Omniauth initializer match what you've configured in the Shopify Partner Dashboard.
内容的提问来源于stack exchange,提问作者Joe Sasson

