After struggling with some SSL issues on my machine, I'm still trying to access a user's Blogger account through the Google Ruby Client API. I'm using the following:
I can successfully authenticate users and access their blogs through the Google API at the time of authentication. When a user logs in, I store the access_token
and refresh_token
I receive from Google. and everything works great until the access_token
expires. I'm trying to build the functionality that exchanges the refresh_token
for a new access_token
, but keep coming up against walls. Using the client documentation as an example, this is the code I'm using:
client = Google::APIClient.new
token_pair = auth.oauth_token # access_token and refresh_token received during authentication
# Load the access token if it's available
if token_pair
client.authorization.update_token!(token_pair.to_hash)
end
# Update access token if expired
if client.authorization.refresh_token && client.authorization.expired?
client.authorization.fetch_access_token!
end
blogger = client.discovered_api('blogger', 'v3')
result = client.execute(
api_method: blogger.blogs.list_by_user,
parameters: {'userId' => "self", 'fields' => 'items(description,id,name,url)'},
headers: {'Content-Type' => 'application/json'})
This code works perfectly while the access_token
is valid. As soon as it expires though, I'm seeing 2 problems:
expires_at
value in the database), client.authorization.expired?
returns false
-- is there a different way I can check the expiration of the token besides using the value in the database?client.authorization.fetch_access_token!
I get an invalid_request
error.Can someone please let me know how I can exchange a refresh_token
for a new access_token
using the client API? Even if you know how to do it in another language, that would be a big help as I can then try to Rubyfy it. Thanks!!
You may have already found this, but you can read through the whole process here at google: https://developers.google.com/accounts/docs/OAuth2WebServer
The omniauth-google-oauth2 strategy already takes care of setting the access_type and approval_prompt so getting a refresh token is just a matter of posting to https://accounts.google.com/o/oauth2/token with grant_type=request_token
Here is roughly the code I use:
def refresh_token
data = {
:client_id => GOOGLE_KEY,
:client_secret => GOOGLE_SECRET,
:refresh_token => REFRESH_TOKEN,
:grant_type => "refresh_token"
}
@response = ActiveSupport::JSON.decode(RestClient.post "https://accounts.google.com/o/oauth2/token", data)
if @response["access_token"].present?
# Save your token
else
# No Token
end
rescue RestClient::BadRequest => e
# Bad request
rescue
# Something else bad happened
end