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

解决Devise集成Omniauth时Rails视图中路径的NameError问题

问题描述

在Rails(结合Spree)应用中实现Omniauth认证时,遇到NameError,提示视图中的Omniauth路径方法未定义。相关代码如下:

视图代码

<div class="social_login">
  <div class="">
    <%= link_to "Sign in with Facebook", user_facebook_omniauth_authorize_path, type: "button", class: "social_box fb" %>
    <%= link_to "Sign in with Google", user_google_oauth2_omniauth_authorize_path, type: "button", class: "social_box google" %>
  </div>
</div>

routes.rb配置

devise_for(:user, {
    class_name: 'Spree::User',
    singular: :spree_user,
    controllers: {
      sessions: 'user_sessions',
      registrations: 'user_registrations',
      passwords: 'user_passwords',
      confirmations: 'user_confirmations',
      omniauth_callbacks: 'users/omniauth_callbacks'
    },

omniauth_controller.rb代码

class OmniauthController < ApplicationController
  def facebook
    @user = Spree::User.create_from_provider_data(request.env['omniauth.auth'])
    if @user.persisted?
      sign_in_and_redirect @user
    else
      flash[:error] = 'There was a problem signing you in through Facebook. Please register or try signing in later.'
      redirect_to new_spree_user_registration_url
    end
  end

  def google_oauth2
    @user = Spree::User.create_from_provider_data(request.env['omniauth.auth'])
    if @user.persisted?
      sign_in_and_redirect @user

    else
      flash[:error] = 'There was a problem signing you in through Google. Please register or try signing in later.'
      redirect_to new_spree_user_registration_url
    end
  end

  def failure
    flash[:error] = 'There was an error signing you in. Please try again.'
    redirect_to root_path
  end
end

需要解决:如何正确引用视图中的Omniauth路径?正确路径是什么?如何确保路径被正确定义?


解决方案

1. 修正视图中的路径名称

因为你在devise_for配置里指定了singular: :spree_user,所以Omniauth路由的前缀是spree_user而非user。视图中的路径需要修改为:

<%= link_to "Sign in with Facebook", spree_user_facebook_omniauth_authorize_path, type: "button", class: "social_box fb" %>
<%= link_to "Sign in with Google", spree_user_google_oauth2_omniauth_authorize_path, type: "button", class: "social_box google" %>

2. 确认路由是否正确生成

运行以下命令查看实际生成的Omniauth路由:

rails routes | grep omniauth

输出结果中应该包含类似这样的路由:

spree_user_facebook_omniauth_authorize GET|POST /users/auth/facebook(.:format) users/omniauth_callbacks#passthru
spree_user_facebook_omniauth_callback GET|POST /users/auth/facebook/callback(.:format) users/omniauth_callbacks#facebook
spree_user_google_oauth2_omniauth_authorize GET|POST /users/auth/google_oauth2(.:format) users/omniauth_callbacks#passthru
spree_user_google_oauth2_omniauth_callback GET|POST /users/auth/google_oauth2/callback(.:format) users/omniauth_callbacks#google_oauth2

如果没有这些路由,说明Omniauth配置不完整。

3. 补全并修正路由配置

你提供的routes.rb代码末尾缺少闭合的}和end,先补全:

devise_for(:user, {
    class_name: 'Spree::User',
    singular: :spree_user,
    controllers: {
      sessions: 'user_sessions',
      registrations: 'user_registrations',
      passwords: 'user_passwords',
      confirmations: 'user_confirmations',
      omniauth_callbacks: 'users/omniauth_callbacks'
    }
})

4. 修正控制器命名与路径

你的路由指定了omniauth_callbacks: 'users/omniauth_callbacks',这意味着控制器需要:

  • 文件路径:app/controllers/users/omniauth_callbacks_controller.rb
  • 类名:Users::OmniauthCallbacksController

修改控制器代码如下:

class Users::OmniauthCallbacksController < ApplicationController
  def facebook
    @user = Spree::User.create_from_provider_data(request.env['omniauth.auth'])
    if @user.persisted?
      sign_in_and_redirect @user
    else
      flash[:error] = 'There was a problem signing you in through Facebook. Please register or try signing in later.'
      redirect_to new_spree_user_registration_url
    end
  end

  def google_oauth2
    @user = Spree::User.create_from_provider_data(request.env['omniauth.auth'])
    if @user.persisted?
      sign_in_and_redirect @user
    else
      flash[:error] = 'There was a problem signing you in through Google. Please register or try signing in later.'
      redirect_to new_spree_user_registration_url
    end
  end

  def failure
    flash[:error] = 'There was an error signing you in. Please try again.'
    redirect_to root_path
  end
end

5. 确保Devise Omniauth初始化配置

在config/initializers/devise.rb中添加Omniauth provider配置(替换为你的实际密钥):

config.omniauth :facebook, 'YOUR_FACEBOOK_APP_ID', 'YOUR_FACEBOOK_APP_SECRET'
config.omniauth :google_oauth2, 'YOUR_GOOGLE_CLIENT_ID', 'YOUR_GOOGLE_CLIENT_SECRET'

只有添加了这些配置,Devise才会自动生成对应的Omniauth路由。


内容的提问来源于stack exchange,提问作者Afaq Shahid Khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:51:31