【问题标题】:Koala Rails AuthenticationKoala Rails 身份验证
【发布时间】:2012-07-04 15:45:01
【问题描述】:

我有以下代码:

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery

  before_filter :current_user

  def facebook_cookies
    @facebook_cookies ||= Koala::Facebook::OAuth.new.get_user_info_from_cookie(cookies).symbolize_keys!
  end

  def current_user
    begin
      # allow for ?access_token=[TOKEN] for iOS calls.
      @access_token = params[:access_token] || facebook_cookies[:access_token]
      @graph = Koala::Facebook::API.new(@access_token)
      # TODO: move this to session[:current_user]..
      @current_user ||= User.from_graph @graph.get_object('me', { fields: 'id,first_name,last_name,gender,birthday' })
    rescue
      nil # not logged in
    end
  end

  def authenticate
    redirect_to(root_url) if current_user.nil?
  end
end

(我已经按照这里https://github.com/arsduo/koala/wiki/Koala-on-Rails的描述设置了考拉)

我真的不想介绍 OmniAuth,因为我想做的事情相当简单。上面的代码有效,问题是它为每个页面加载调用 Facebook = 不好。我猜我需要存储session[:user_id],然后在用户通过身份验证后为每个后续请求调用User.find(session[:user_id])

谁能提出解决这个问题的最有效方法,这样我就不用在每个页面加载时等待 Facebook 了?

【问题讨论】:

  • get_user_info_from_cookie 方法也向 Facebook 发出请求,仅供参考。所以在你上面的代码中,你发出了 2 个请求

标签: ruby-on-rails facebook authentication koala


【解决方案1】:

你可以试试这样的:

class ApplicationController < ActionController::Base
  protect_from_forgery

  before_filter :current_user, if: Proc.new{ !current_user? }

  def facebook_cookies
    @facebook_cookies ||= Koala::Facebook::OAuth.new.get_user_info_from_cookie(cookies).symbolize_keys!
  end

  def current_user
    begin
      # allow for ?access_token=[TOKEN] for iOS calls.
      @access_token = params[:access_token] || facebook_cookies[:access_token]
      @graph = Koala::Facebook::API.new(@access_token)
      # TODO: move this to session[:current_user]..
      @current_user ||= User.from_graph @graph.get_object('me', { fields: 'id,first_name,last_name,gender,birthday' })
    rescue
      nil # not logged in
    end
  end

  def authenticate
    redirect_to(root_url) if current_user.nil?
  end

  def current_user?
    !!@current_user
  end
end

【讨论】:

  • 嗯,但这仍然不会在每个页面加载时运行 @graph.get_object(..) 吗?我在想我需要在某个时候将它粘贴到会话变量中?
【解决方案2】:

我有一个用于我的 facebook 身份验证和授权的实现。 代码分为非状态改变方法和状态改变方法。

请随意使用代码。

## checks if we have access to fb_info and it is not expired
## Non stagechanging
def oauth_is_online
  return !(session[:fb_cookies].nil? or session[:fb_cookies]['issued_at'].to_i + session[:fb_cookies]['expires'].to_i < Time.now.to_i - 10)
end

## checks if the user is in the database
## Non stats changing
def oauth_is_in_database
  return oauth_is_online && 0 < User.where(:fb_id => session[:fb_cookies]['user_id']).count
end

## Returns true if it is the specified user
## Non stagechanging
def oauth_is_user(user)
  return oauth_is_online && session[:fb_cookies]['user_id'] == user.fb_id
end

## Requires the user to be online. If not, hell breaks loose.
def oauth_require_online
  if !oauth_ensure_online
    render :file => "public/401.html", :status => :unauthorized, :layout => false
    return false
  end
  return session[:fb_cookies]
end

## Requires the user to be online and the correct user. If not, hell breaks loose.
def oauth_require_user(user)
  c = oauth_require_online
  return false unless c
  return c unless !oauth_is_user(user)
  render :file => "public/403.html", :status => :unauthorized, :layout => false
  return false
end


## Ensures that the user is online  
def oauth_ensure_online
  begin
    # Checks if the user can be verified af online
    if !oauth_is_in_database
      # the user is not online. Now make sure that they becomes online.
      logger.info "Creates new FB Oauth cookies"
      fb_cookies = Koala::Facebook::OAuth.new.get_user_info_from_cookie(cookies)

      # TODO In the future the session should be reset at this point
      # reset_session
      session[:fb_cookies_reload] = false
      session[:fb_cookies] = fb_cookies

      logger.info "Updating user in database."

      # Tries to load the user
      @current_user = User.where(:fb_id => session[:fb_cookies]['user_id']).first
      logger.info "User exists? => #{@current_user.nil?}"

      # creating if not found
      @current_user = User.new(:fb_id => session[:fb_cookies]['user_id']) unless !@current_user.nil?

      # Loading graph
      @fb_graph = Koala::Facebook::API.new(session[:fb_cookies]['access_token'])

      # Loading info from graph
      me = @fb_graph.get_object('me')

      @current_user.name_first = me['first_name'].to_s
      @current_user.name_last = me['last_name'].to_s
      @current_user.email = me['email'].to_s
      @current_user.fb_access_token = session[:fb_cookies]['access_token'].to_s

      # Saving the updated user
      @current_user.save!
      return oauth_is_online
    else
      # the user is online. Load variables.
      @current_user = User.where(:fb_id => session[:fb_cookies]['user_id']).first
      @fb_graph = Koala::Facebook::API.new(@current_user.fb_access_token)
    end
    return oauth_is_online
  rescue Koala::Facebook::OAuthTokenRequestError => oe
    ## TODO handle the diferent errors
    # user is not online on facebook
    # user have not authenticatet us
    # token is used allready once.
    logger.debug "FB koala OAuthTokenRequestError: #{oe}"
    return false
  end
end

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 2011-02-21
    • 2016-04-12
    • 1970-01-01
    • 2012-12-28
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多