session[:user_id] 即使用户登录 Rails 也返回 nil

session[:user_id] returning nil even if user signed in Rails

omniauth_callbacks_controller

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

def facebook

 @user = User.from_omniauth(request.env["omniauth.auth"])

 if @user.persisted?
  sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
  set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
 else
  session["devise.facebook_data"] = request.env["omniauth.auth"]
  redirect_to new_user_registration_url
  end
 end
end

session_controller

class SessionsController < ApplicationController

 def create
  user = User.from_omniauth(env["omniauth.auth"])
  #sign_in(:user, user)
  session[:user_id] = user.id 
  redirect_to root_url
 end

 def destroy
  session[:user_id] = nil
  redirect_to root_url
 end
end

application_controller

 class ApplicationController < ActionController::Base
    # Prevent CSRF attacks by raising an exception.
    # For APIs, you may want to use :null_session instead.
       protect_from_forgery with: :exception
    private
    helper_method :current_user
    def current_user
         @current_user = User.find(session[:user_id])  
    end

  end

user.rb

   class User < ActiveRecord::Base
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable,:omniauthable, :omniauth_providers => [:facebook]
      belongs_to :restaurant, foreign_key: 'restaurant_id'
      has_many :orders
      def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
        user.provider = auth.provider
        user.uid = auth.uid
        user.name = auth.info.name
        user.oauth_token = auth.credentials.token
        user.email = auth.info.email
        user.password = Devise.friendly_token[0,20]
        user.oauth_expires_at = Time.at(auth.credentials.expires_at)

      end
  end
end

visitor_controller

 class VisitorsController < ApplicationController

   def index
     @user = current_user

   end
 end

这是我的应用程序的根页面控制器。 我正在创建一个餐厅点餐应用程序,但问题是所有订单都显示给所有用户。

所以我需要让每个订单用户具体化。 但是我无法从我的任何控制器访问 'user.id'。

请帮忙。 找不到问题。 谢谢。

如果您有一个打算同时使用 Devise 和 OmniAuth 的应用程序,则无需创建自定义 SessionsController

您只需要 customize to the login page 和 link:

<%= link_to "/auth/facebook", "Sign in with Facebook" %>

请注意,新用户和回访用户将使用相同的回调 URL!

sign_in_and_redirect在您的 Users::OmniauthCallbacksController 中将在 Warden 的帮助下处理会话中的用户序列化,您可以通过普通的 Devise 控制器注销用户。


编辑

你最大的问题似乎是理解 OmniAuth 和 Devise 如何协同工作。

Devise 提供普通用户/密码注册和会话所需的所有功能。

OmniAuth 为处理不同的 OAuth 提供者和处理 OAuth 的细节提供了抽象。

您的回调控制器需要做的就是调用 Devises sign_in_and_redirect 方法,它将负责通过 Warden 在会话中序列化用户。