我从twitter手动请求请求令牌并将回调传递给设备的默认页面,但收到错误
Started GET "/users/auth/twitter/callback?device=mobile&oauth_token=mVpOFb1ruczKw7LzbgQYX73nq81hiw5OEBSOpob5rJk&oauth_verifier=WzBwpFdf7rYDH4DDWNbIfYPkHrIUzam9Ld6vskQrzNA" for 127.0.0.1 at 2014-02-03 18:00:03 +0400
omniauth: (twitter) Authentication failure! invalid_credentials: OAuth :: Unauthorized, 401 Unauthorized
如果我通过Devise登录,一切都没有错误。说明花了here。为什么会这样?
class Api::TwitterController < ApplicationController
def get_auth_token
consumer_key = OAUTH_KEYS[Rails.env]['twitter']['client_id'] # Obtainable from your destination site's API admin panel
consumer_secret = OAUTH_KEYS[Rails.env]['twitter']['secret_key'] # As above
callback_url = user_omniauth_callback_url(:twitter, device: :mobile)
method = 'POST'
uri = 'https://api.twitter.com/oauth/request_token'
params = set_params(consumer_key)
params['oauth_callback'] = url_encode(callback_url)
params['oauth_signature'] = url_encode(sign(consumer_secret + '&', signature_base_string(method, uri, params)))
token_data = parse_string(request_data(header(params), uri, method))
auth_token, auth_token_secret = [token_data['oauth_token'], token_data['oauth_token_secret']] # save these values, they'll be used again later
redirect_to "https://api.twitter.com/oauth/authorize?oauth_token=#{auth_token}"
end
private
# where parse_string is simply
def parse_string(str)
ret = {}
str.split('&').each do |pair|
key_and_val = pair.split('=')
ret[key_and_val[0]] = key_and_val[1]
end
ret
end
def set_params(consumer_key)
params = {
'oauth_consumer_key' => consumer_key, # Your consumer key
'oauth_nonce' => generate_nonce, # A random string, see below for function
'oauth_signature_method' => 'HMAC-SHA1', # How you'll be signing (see later)
'oauth_timestamp' => Time.now.getutc.to_i.to_s, # Timestamp
'oauth_version' => '1.0' # oAuth version
}
end
def generate_nonce(size=7)
Base64.encode64(OpenSSL::Random.random_bytes(size)).gsub(/\W/, '')
end
def signature_base_string(method, uri, params)
# Join up the parameters into one long URL-safe string of key value pairs
encoded_params = params.sort.collect{ |k, v| url_encode("#{k}=#{v}") }.join('%26')
# Join the above with your method and URL-safe destination URL
method + '&' + url_encode(uri) + '&' + encoded_params
end
# I'm a PHP developer primarily, hence the name of this function!
def url_encode(string)
CGI::escape(string)
end
# where sign is:
def sign(key, base_string)
digest = OpenSSL::Digest::Digest.new('sha1')
hmac = OpenSSL::HMAC.digest(digest, key, base_string)
Base64.encode64(hmac).chomp.gsub(/\n/, '')
end
# where header is:
def header(params)
header = "OAuth "
params.each do |k, v|
header += "#{k}=\"#{v}\", "
end
header.slice(0..-3) # chop off last ", "
end
def request_data(header, base_uri, method, post_data=nil)
url = URI.parse(base_uri)
http = Net::HTTP.new(url.host, 443) # set to 80 if not using HTTPS
http.use_ssl = true # ignore if not using HTTPS
if method == 'POST'
# post_data here should be your encoded POST string, NOT an array
resp, data = http.post(url.path, post_data, { 'Authorization' => header })
else
resp, data = http.get(url.to_s, { 'Authorization' => header })
end
resp.body
end
end
答案 0 :(得分:0)
问题解决了,有必要在会话中添加一些数据
auth_token, auth_token_secret = [token_data['oauth_token'], token_data['oauth_token_secret']]
session['oauth'] ||= {}
session['oauth']['twitter'] ||= {}
session['oauth']['twitter']['request_token'] = auth_token
session['oauth']['twitter']['request_secret'] = auth_token_secret
session['oauth']['twitter']['callback_confirmed'] = true