2

我正在尝试使用 OmniAuth 向 Rdio 进行身份验证 - 我的应用程序已经使用 Omniauth 策略成功地通过 Twitter 进行了身份验证

尝试使用omniauth-rdio gem,但似乎失败了:https ://github.com/nixme/omniauth-rdio

任何反馈或见解将不胜感激!我从来没有遇到过 OAuth 的 403 错误,所以我不确定如何继续

错误:

OAuth::Unauthorized (403 Forbidden):
  oauth (0.4.6) lib/oauth/consumer.rb:216:in `token_request'
  oauth (0.4.6) lib/oauth/consumer.rb:136:in `get_request_token'
  omniauth-oauth (1.0.1) lib/omniauth/strategies/oauth.rb:29:in `request_phase'
  omniauth (1.1.0) lib/omniauth/strategy.rb:207:in `request_call'
  omniauth (1.1.0) lib/omniauth/strategy.rb:174:in `call!'
  omniauth (1.1.0) lib/omniauth/strategy.rb:157:in `call'
  omniauth (1.1.0) lib/omniauth/strategy.rb:177:in `call!'
  omniauth (1.1.0) lib/omniauth/strategy.rb:157:in `call'
  omniauth (1.1.0) lib/omniauth/strategy.rb:177:in `call!'
  omniauth (1.1.0) lib/omniauth/strategy.rb:157:in `call'
  omniauth (1.1.0) lib/omniauth/builder.rb:48:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
  rack (1.4.1) lib/rack/etag.rb:23:in `call'
  rack (1.4.1) lib/rack/conditionalget.rb:25:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/head.rb:14:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/flash.rb:242:in `call'
  rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context'
  rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call'
  actionpack (3.2.6) lib/action_dispatch/middleware/cookies.rb:338:in `call'

我的路线文件:

Autotune::Application.routes.draw do

  get "sessions/twitter", as: :twitter_signin
  get "sessions/rdio", as: :rdio_signin

  root to: 'static_pages#home'

  match '/about',   to: 'static_pages#about'

  match '/signout' => 'sessions#destroy', :as => :signout
  match '/auth/:provider/callback', to: 'sessions#create'

Omniauth 初始化器:

Rails.application.config.middleware.use OmniAuth::Builder do
  provider :developer unless Rails.env.production?

  provider :twitter, Rails.application.config.twitter[:key], Rails.application.config.twitter[:secret]

  provider :rdio, Rails.application.config.rdio[:key], Rails.application.config.rdio[:secret]

  OmniAuth::Configuration.instance.on_failure = OmniAuthFailureEndpoint
end

class OmniAuthFailureEndpoint < OmniAuth::FailureEndpoint
  def call
    Rack::Response.new(["302 Moved"], 302, 'Location' => "/sessions/failure?#{env['QUERY_STRING']}").finish
  end
end

会话控制器:

class SessionsController < ApplicationController

  def rdio
    unless params[:return_to].blank?
      session[:return_to] = params[:return_to]
    end

    redirect_to '/auth/rdio'
  end

  def twitter
    unless params[:return_to].blank?
      session[:return_to] = params[:return_to]
    end

    redirect_to '/auth/twitter'
  end


  def create
    auth_hash = request.env['omniauth.auth']
    token = request.env['omniauth.strategy'].access_token.token
    user = User.sign_in_with_auth_hash(auth_hash, token)

    login_user(user)
    return_to_url(root_path)
  end

  def destroy
    logout_user
    return_to_url('/', notice: "You have successfully logged out")
  end


  def update
    ##update twitter
  end

  private

  def auth_hash
    request.env['omniauth.auth']
  end

应用控制器:

class ApplicationController < ActionController::Base
  protect_from_forgery

  before_filter :check_valid_session

  ### authentication:
  helper_method :authenticated?, :session_user, :session_user_id

  def check_valid_session
    begin
      if session[:user_id] and session_user.nil?
        session.clear
        flash[:warning] = "Your session has expired"
      end
    rescue
      logout_user
    end
  end

  # returns true if the currently accessed user account is the same as the session user
  def is_session_user?
    id_or_username = params[:user_id]
    case id_or_username
      # if the id/username is for the current user, or the id is not provided then use the current user
      when session_user_id, nil
        true
      else
        false
    end
  end

  def authenticated?
    !session_user_id.blank?
  end

  def session_user
    @session_user ||= User.find(session[:user_id]) if authenticated?
  end

  def session_user_id
    session[:user_id]
  end

  # ensures that the user is authenticated
  def authenticate_user!(options = {})
    defaults = {
        return_to: request.original_url,
        controller: :session,
        action: :twitter,
        raise_exception: false

    }

    defaults.merge!(options)
    options = defaults;

    if authenticated?
      true
    elsif options[:raise_exception]
      raise "User is not authenticated"
    else
      session[:return_to] = options[:return_to]
      redirect_to '/auth/twitter'
      false
    end
  end

  def login_user(user)
    # this is the one value we need to retain from the session after we reset it
    return_to = session[:return_to]
    update_session(user)
    session[:return_to] = return_to
  end

  def update_session(user = session_user)
    reset_session
    @session_user = user
    refresh_session
  end

  def refresh_session
    session[:user_id] = @session_user.id
    session[:twitter_id] = @session_user.twitter_id
    session[:twitter_name] = @session_user.twitter_name
    session[:rdio_id] = @session_user.rdio_id
  end

  def logout_user
    reset_session
    @session_user = nil
  end

  def return_to_url(default_return_to = nil, options = {})
    return_to = params[:return_to] || session[:return_to] || default_return_to
    if !return_to.blank?
      session[:return_to] = nil
      redirect_to return_to, options
      true
    else
      false
    end
  end

end

用户型号:

class User < ActiveRecord::Base

  def self.sign_in_with_auth_hash(auth_hash, access_token)
    user = User.find_by_auth_hash(auth_hash)

    if user
      return user
    end

    if auth_hash[:provider] == 'twitter'
      user = User.new
      #user.name = auth_hash['info']['name']
      user.twitter_id = auth_hash['uid']
      user.twitter_name = auth_hash['info']['nickname']
      user.twitter_token = auth_hash['credentials']['token']
      user.twitter_secret = auth_hash['credentials']['secret']
      user.email = rand(1000000000).to_s
      user.encrypted_password = 'notnull'
    end

    if auth_hash[:provider] == 'rdio'
      user = User.new
      #user.name = auth_hash['info']['name']
      user.rdio_id = auth_hash['uid']
      user.rdio_name = auth_hash['info']['nickname']
      user.rdio_token = auth_hash['credentials']['token']
      user.rdio_secret = auth_hash['credentials']['secret']
      user.email = rand(1000000000).to_s
      user.encrypted_password = 'notnull'
    end

    user.save!
    user
  end

  def self.find_by_auth_hash(auth_hash)
    case auth_hash[:provider]
      when 'twitter'
        User.where(twitter_id: auth_hash['uid']).first
      else
        nil
    end
  end  
end
4

0 回答 0