So I have a web app with ruby on rails that connects to google drive's API. Up until now, it used to receive the refresh token, since one of the paramenters I was using was offline. But recently it stopped getting it. The url that is being sent is this:
Redirected to https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=ID&options=%7B:access_type=%3E%22offline%22,%20:approval_prompt=%3E%22force%22%7D&redirect_uri=http://localhost:3000/oauth2callbackdrive&response_type=code&scope=https://www.googleapis.com/auth/drive%20https://www.googleapis.com/auth/userinfo.email
The code that is redirecting to the URI has this:
client = Google::APIClient.new
client.authorization.client_id = GOOGLE_CLIENT_ID
client.authorization.client_secret = GOOGLE_CLIENT_SECRET
client.authorization.scope = SCOPES
client.authorization.redirect_uri = GOOGLE_CLIENT_REDIRECT_URI
auth_url = client.authorization.authorization_uri(:options => {:access_type => :offline, :approval_prompt => :force}.to_s)
redirect_to auth_url.to_s
On the callback function I have this:
client = Google::APIClient.new
client.authorization.client_id = GOOGLE_CLIENT_ID
client.authorization.client_secret = GOOGLE_CLIENT_SECRET
client.authorization.scope = SCOPES
client.authorization.redirect_uri = GOOGLE_CLIENT_REDIRECT_URI
client.authorization.code = params['code']
client.authorization.fetch_access_token!
And on the same function I insert into the database:
CloudAccount.create(username: username,access_token:client.authorization.access_token, refresh_token:client.authorization.refresh_token,register_id:userID,cloud_name:'drive')
Problem is, the client.authorization.refresh_token, which had a value before, now is returning empty and so it's being inserted into the DB as NULL. Which affects uploads/refresh/downloads when the access_token expires.
What can I do or what am I doing wrong?
Thanks.
I was having a similar issue (Getting a refresh token from google api). I think if you use:
prompt='select_account consent'
then that forces a new approval screen and you get a new refresh_token.
Reference: https://developers.google.com/identity/protocols/OAuth2UserAgent
Related
I am trying to develop a simple tool that uses Authlib OAuth2 server to get refresh tokens but example server here does not issue a refresh token. When I print the token I get the following:
{'access_token': '....', 'scope': 'profile', 'token_type': 'Bearer', 'expires_in': 864000, 'expires_at': 1532191887}
The flow is Authorization code as referred here; first I handle the consent part:
client_id = '...'
client_secret = '.....'
scope = '...'
session = OAuth2Session(client_id, client_secret, scope=scope)
authorize_url = '.../oauth/authorize'
uri, state = session.authorization_url(authorize_url)
Then I try to get the token:
urlset = '.../?code=...&state=...'
access_token_url = '.../oauth/token'
token = session.fetch_access_token(access_token_url,authorization_response=urlset)
Add a config of OAUTH2_REFRESH_TOKEN_GENERATOR=True, added in commit:
https://github.com/authlib/example-oauth2-server/commit/4f2f48cc3e74b631d9c4c3bdf8558da3de7365a2
See documentation: https://docs.authlib.org/en/latest/flask/2/
I can't seem to get a refresh_token whenever I'm authorized, I've tried setting headers, kind of like how it would be done with google oauth, but not luck. Here's my process:
Using oauth2 gem
Instantiate client
client = OAuth2::Client.new(
salesforce_app_key,
salesforce_secret_key,
site: 'https://login.salesforce.com/services/oauth2/',
authorize_url: 'https://login.salesforce.com/services/oauth2/authorize',
token_url: 'https://login.salesforce.com/services/oauth2/token',
raise_errors: false
)
Authorize connection
auth = client.auth_code.authorize_url(
redirect_uri: 'https://my_app_callback.com/oauth/authorize'
)
Fetch token
token = client.auth_code.get_token(
code,
redirect_uri: 'https://my_app_callback.com/oauth/authorize'
)
From this point, I have the connection set, but when I do token.refresh_token I get a nil value.
By using:
access_token = OAuth2::AccessToken.new(oauth, token)
The session was reestablished successfully. It's in the docs, but not written in a way I could uderstand it's used to reauthenticate.
Following is what I am trying to do -
client = Google::APIClient.new
client.authorization.client_id = 'XXXX'
client.authorization.client_secret = 'XXXXX'
client.authorization.scope = 'https://www.googleapis.com/auth/calendar'
client.authorization.redirect_uri = 'http://www.aaaaa.com/'
calendar = client.discovered_api('calendar', 'v3')
In order to get access_token to make further requests, i make a call to
client.authorization.fetch_access_token!
Response I get is :
Signet::AuthorizationError: Authorization failed. Server message:
{
"error" : "invalid_request"
}
from D:/main/tools/jruby/lib/ruby/gems/1.8/gems/signet-0.4.4/lib/signet/oauth_2/client.rb:865:in `fetch_access_token'
Later I changed made a few changes and set the grant_type to password and supplied user name and password.
client.authorization.grant_type = 'password'
client.authorization.username = 'aaaaa'
client.authorization.password = 'aaaaa'
Still facing the same issue.
Documentation is not of much help. Is there any setting that I am missing?
You probably already figured this out, but I think I know what the problem is. You must first navigate (in a browser) to client.authorization.authorization_uri, which is where you will be asked to grant access to the Google account. After that, you will be redirected to client.authorization.redirect_uri, which is http://www.aaaaa.com/ in the code you provided. There will be an authorization code appended on to the URL: http://www.aaaaa.com?code=<code here>. You must set client.authorization.code equal to that authorization code. Once you have done that, you should be able to call client.authorization.fetch_access_token! and then make calls to the API.
I'm trying to make authenticated calls to the Bitbucket REST API, with Oauth authentication. I've successfully retrieved an oauth_token and an oauth_token_secret (although they are the same as the request_token and request_token_secret, which seems strange but not outside of the spec). When I make an API call to another endpoint, I get a 401 (not authenticated). I've tried using header authentication and/or passing the oauth_token and oauth_token_secret as HTTP params with the sane result.
Here's the code:
account_name_url = 'https://api.bitbucket.org/1.0/user'
feedback_oauth_hook = OAuthHook(
access_token='REDACTED',
access_token_secret='ALSO_REDACTED',
consumer_key=CLIENT_ID,
consumer_secret=CLIENT_SECRET,
header_auth=True
)
params = {
'access_token': auth_tokens['access_token'],
'access_token_secret': auth_tokens['access_secret']
}
response = requests.get(account_name_url, data=params, hooks={'pre_request': feedback_oauth_hook})
import oauth2 #pip install oauth2
accessToken = oauth2.Token(OAUTH_TOKEN, OAUTH_TOKEN_SECRET)
consumer_key = YOUR_COMSUMER_KEY
consumer_secret = YOUR_CONSUMER_SECRET
consumer = oauth2.Consumer(consumer_key, consumer_secret)
client = oauth2.Client(consumer, accessToken)
api_url = "https://api.bitbucket.org/1.0/user"
resp, content = client.request(api_url, "GET")
print resp, content
The above python code works for me.
I print the request info, notice that it contains oauth_version=1.0 which is required.
I tried removing it, then 401 was returned. I think BitBucket should document this.
I am trying to use the scribe oAuth plugin (in a grails environment). I am able to get the user to authorize my app and authenticate. I can then get the xml response. my question, though, is how do I re-query a users profile without having to have them re-authorize my app. Once they authorize it the first time, I capture their Token and Secret key. So, shouldn't I be able to re-query the profile (as long as they do not revoke their authorization.)? I was able to do this with the older version of the plugin. The problem is with creating a new token. I don't see a way to create the Authorization token without the Verifier and Request Token (which wont exist because my code is executing the query on their behalf, with their permission.)
If I try to create the token like this:
Token accessToken = new Token()
accessToken.secret="XXX"
accessToken.token = "YYY"
I get an initialization error.
I can't create it like this, because I dont have the Request token and verifier:
Token accessToken = service.getAccessToken(requestToken, verifier);
accessTokenSecret = accessToken.secret
accessTokenKey = accessToken.token
And If i dont have the access token object, I am unable to sign my request. The full code looks like this (assuming their is a request token and verifier)
OAuthService service=new ServiceBuilder()
.provider(LinkedInApi.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.build();
Verifier v = new Verifier(ver);
Token accessToken = service.getAccessToken(rt, v);
accessTokenSecret = accessToken.secret
accessTokenKey = accessToken.token
OAuthRequest request = new OAuthRequest(Verb.GET, apiUrl);
service.signRequest(accessToken, request);
Response response = request.send();
xmlString=response.getBody();
Thanks for your help
jason
well, after some time, I got this to work:
public getProfileWithTokens(getAccessToken, getAccessTokenSecret){
Token newAccessToken = new Token(getAccessToken, getAccessTokenSecret);
String xmlString =""
OAuthService service=new ServiceBuilder()
.provider(LinkedInApi.class)
.apiKey(apiKey)
.apiSecret(apiSecret)
.build();
OAuthRequest request = new OAuthRequest(Verb.GET, apiUrl);
service.signRequest(newAccessToken, request);
Response response = request.send();
xmlString=response.getBody();
}