How can I tell if Tumblr OAuth credentials are valid?
Using the ruby OAuth library, I am trying to verify if a previous user's credentials are still valid. (in case he has revoked privileges to my app) I've done it for Twitter with no problem as there is a handy .authenticated? method in the Twitter OAuth library. Using the generic library though, I can find no similar methods.
@consumer = OAuth::Consumer.new(
ENV['TUMBLR_CONSUMER_KEY'],
ENV['TUMBLR_CONSUMER_SECRET'],
{ :site => 'http://www.tumblr.com',
:request_token_path => '/oauth/request_token',
:authorize_path => '/oauth/authorize',
:access_token_path => '/oauth/access_token',
:http_method => :get
}
)
@access_token = OAuth::AccessToken.new(@consumer, @tumblrauth['access_token'], @tumblrauth['access_token_secret'])
puts @access_token.inspect
@resp = @access_token.get('api/read')
puts @resp.inspect
I get a server error as soon as I try the @access_token.get() call, something about nill not having a downcase method, I'm guessing it's expecting a string of some kind instead. But I don't know what param it's referring to.
The access_token and secret that I'm using were previously functional, but I revoked开发者_运维知识库 access to the app to test how to detect that. I just need some way to know that the user is no longer registered with that service, so I can switch the state.
Here is a stack trace:
NoMethodError - undefined method 'downcase' for nil:NilClass:
/Library/Ruby/Gems/1.8/gems/oauth-0.4.4/lib/oauth/request_proxy/base.rb:93:in 'normalized_uri'
/Library/Ruby/Gems/1.8/gems/oauth-0.4.4/lib/oauth/request_proxy/base.rb:113:in 'signature_base_string'
/Library/Ruby/Gems/1.8/gems/oauth-0.4.4/lib/oauth/signature/base.rb:77:in 'signature_base_string'
Try:
@resp = @access_token.get('http://www.tumblr.com/api/read/json')
Edit, as per comments below:
#Monkey Patch the Oauth gem to fit the "tumblr" way of doing Oauth
class Net::HTTP
def address=(new_address)
@address = new_address
end
end
module OAuth
class Consumer
def tumblr_address=(address)
@tumblr_address = address
@orig_address = self.http.address
end
def create_signed_request(http_method, path, token = nil, request_options = {}, *arguments)
# Use the original address to generate OAuth signature
self.http.address = @orig_address if @orig_address
request = create_http_request(http_method, path, *arguments)
sign!(request, token, request_options)
# Submit the request to the tumblr address
self.http.address = @tumblr_address if @tumblr_address
request
end
end
end
module OAuth
class RequestToken
def get_access_token(options = {}, *arguments)
response = consumer.token_request(consumer.http_method, (consumer.access_token_url? ? consumer.access_token_url : consumer.access_token_path), self, options, *arguments)
self.consumer.tumblr_address = response[:subdomain]
OAuth::AccessToken.from_hash(consumer, response)
end
end
end
and then in your controller after your @consumer creation, add this:
@consumer.tumblr_address = "http://user.tumblr.com"
Note: this is untested code, so YMMV.
The only way I could get this to work without the user's Tumblr username, is using the new v2 API. Docs here: http://www.tumblr.com/docs/en/api/v2
@access_token.get('http://api.tumblr.com/v2/user/dashboard?limit=1')
Returns a small JSON envelope with a 200 OK, or a 401 Unauthorized if the tokens are bad.
Now I have to figure out how to get the user's blog name since you can't seem to post to the default blog anymore. Fortunately, you can use both v2 and v1 APIs at the same time.
精彩评论