我正在尝试使用 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