I'm developing RoR application, which allows user to login with google account and download/upload report data from one of his analytics account.
I use omniauth-google-oauth2 gem for authorization with google account and google-api-client for interaction with Google Analytics.
The problem is that when I try to get accounts list with analytics.management.accounts.list method, passing google token as one of authorization parameters, GA responds with 403 Insufficient permissions error.
I suppose, I have to make user to give permission for reading Analytics data in process of authorization. How can I do this?
I've read a lot of related questions, but didn't find solution to my exact problem.
Here is the code:
require 'google/api_client'
client = Google::APIClient.new(:application_name => 'something you like', :application_version => '1')
client.authorization.access_token = 'HERE_GOES_TOKEN'
ga = client.discovered_api('analytics', 'v3')
client.execute(:api_method => ga.management.accounts.list)
Solved the problem! I had to write proper scopes in OAuth configs.
Rails.application.config.middleware.use OmniAuth::Builder do
provider :google_oauth2, PROVIDER_KEY, PROVIDER_SECRET,
{
:scope => "email, profile, https://www.googleapis.com/auth/analytics, https://www.googleapis.com/auth/analytics.edit, https://www.googleapis.com/auth/analytics.manage.users, https://www.googleapis.com/auth/analytics.readonly",
}
end
Related
I'm trying to implement OpenId Connect for QuickBooks, as they are deprecating in 2019 OAuth1.
In the documentation here, I have first to prepare an authorization request to redirect the user to the Intuit OAUth 2.0 server.
To handle all the process, I use the omniauth strategy gem omniauth-quickbooks-oauth2. Here is the omniauth setup:
Rails.application.config.middleware.use OmniAuth::Builder do
# Open ID Connect
provider(
:quickbooks_oauth2,
ENV['INTUIT_CLIENT_ID'],
ENV['INTUIT_CLIENT_SECRET'],
scope: 'com.intuit.quickbooks.accounting openid profile email phone address',
sandbox: Rails.env.development?,
)
end
It generates the following request:
https://appcenter.intuit.com/connect/oauth2?client_id=MYCLIENTID&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fauth%2Fquickbooks_oauth2%2Fcallback&response_type=code&scope=com.intuit.quickbooks.accounting+openid+profile+email+phone+address&state=71f636c1097f8d5bf07a66df5ca64ec43800ea90f6bcedca
Once the user grants the access, Intuit redirect to my redirect URL, and after the user authentification, I get the Authorization code from the params to request the tokens.
For this I use the Gem oauth2
oauth_params = {
:site => "https://appcenter.intuit.com/connect/oauth2",
:authorize_url => "https://appcenter.intuit.com/connect/oauth2",
:token_url => "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer"
}
client = OAuth2::Client.new(ENV['INTUIT_CLIENT_ID'], ENV['INTUIT_CLIENT_SECRET'], oauth_params)
client.auth_code.get_token(authorization_code,
:redirect_uri => 'http://localhost:3000/auth/quickbooks_oauth2/callback',
:grant_type => "authorization_code")
I then obtain an error message:
OAuth2::Error: invalid_grant:
{"error":"invalid_grant"}
I checked my call back uri are the same on the Intuit developer portal:
http://localhost:3000/auth/quickbooks_oauth2/callback
When I try my code to obtain the tokens from the authorization code I obtained from the Intuit OAUth2 Playground, it works!
Which make me believe the issue may be coming from the implementation of Omniauth, But I'm stucked!
I'm using the google-api-client gem in my Rails project. I have omniauth and devise working, and I have users authenticate through Google.
I thought I had this going very well, until recently. I've noticed my app will throw an error when it fetches the Google Calendar API after one hour. The expiration is one hour from authentication time, and from then I get this error:
Signet::AuthorizationError (Authorization failed. Server message:
{
"error" : "invalid_grant",
"error_description" : "Token has been revoked."
}):
This is separate from invalid refresh tokens, as I do have the refresh token stored in the database. It is sending the refresh token request, which spurs that error above, with this code:
client = Google::APIClient.new(
:application_name => APP_NAME,
:application_version => APP_VERSION,
)
client.authorization.client_id = CLIENT_ID
client.authorization.client_secret = CLIENT_SECRET
client.authorization.refresh_token = user.auth_refresh_token
token_result = client.authorization.fetch_access_token!
I have been very careful as to not sign in and out of my Google accounts, so I cannot figure out why Google would send back this message. If I refresh the page after 55 minutes, all is okay. If I refresh the page after 1 hour, it complains about the access token being revoked.
Has anyone had this issue before? If so, what did you do to fix it? Was it something you had to change in Google's Developer Console?
I ended up figuring out the issue, so I thought I'd share what fixed it.
In config/initializers/devise.rb, I have:
scope: 'userinfo.profile, userinfo.email, calendar, https://www.googleapis.com/auth/gmail.readonly', prompt: 'select_account consent' }
What did it for me was the prompt: 'select_account consent' part. Asking the user for consent at each login seems to keep the refresh token up to date. When the user logs in via Google I check if there was a refresh token in the response, and if there was I save that to the database. If not, I keep their current refresh token in the database.
In all honesty, I really don't get why it was necessary for me to do this but for other users who've shared their code examples it was fine. Perhaps there was a change in the Google's OAuth2 or maybe there's a discrepancy in my method of handling the authorization.
I'm planning to use rails-api for providing JSON API for iOS mobile application to consume. The process:
User open the mobile app
User taps on Facebook connect
Mobile app get fb_access_token and post it to API server to identify the user
API server get user profile on Facebook by using fb_access_token
API server either create and look up the user, then response with a api_token for this particular user
Mobile app use the api_token response for all communication afterward.
Which authentication should be the best option for this app? oAuth2 or BasicAuth? I tried rails-api with doorkeeper, but it doesn't work out of the box because doorkeeper need some assets.
I am doing a basic authentication for this integrated with devise.
First i get the post parameters from the mobile application (the access_token and other stuff).
Then I use open-api to get the user details from facebook:
url = "https://graph.facebook.com/me?access_token="
begin
content = open(URI.encode(url + params[:user][:access_token]))
rescue OpenURI::HTTPError #with this I handle if the access token is not ok
return render :json => {:error => "not_good_access_token" }
end
Now Facebook returns the response
status = content.status[0]
content = ActiveSupport::JSON.decode(content)
if status == "200"
#get the email and check if the user is already in the database. If there is not email, check by the facebook id
#If the user exists return the user. If the user does not exists create new
Hope this helps
Than you can user the same code also for google, just change the url to "https://www.googleapis.com/oauth2/v2/userinfo?access_token="
I'd give omniauth-facebook at try, as it uses OAuth2 and is pretty easy to use. All omniauth strategies are rails middleware, so you just need to add gem 'omniauth-facebook' to your gemfile and add the following to config/initializers/omniauth.rb and you will be able to use /auth/facebook to log in via facebook and /auth/facebook/callback to create the user session (you might want to alter the :display key-value as pop-ups in mobile might not be aesthetically pleasing):
Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'],
:scope => 'email,user_birthday,read_stream', :display => 'popup'
end
The facebook auth token will be in the request.env['omniauth.auth'][:credentials][:token] that gets returned to your callback endpoint, which you can integrate into your mobile authentication strategy. see the above link and the omniauth main page for more details.
I am having trouble figuring out how to make a request to the Google Contacts API after a successful authentication.
provider :google_oauth2, "key", "secret", :scope => "userinfo.profile,https://www.google.com/m8/feeds", :approval_prompt => 'auto'
This successfully authenticates the user with permission to access the contact api.
My question is - how do I make the next request to actually get the contacts using the refresh token and other information provided by:
request.env['omniauth.auth']
I've read that you need to specify specific headers like GData-Version => 3.0 but can't seem to figure out how the entire request would look like.
Thank you!
UPDATE 2011/05/01:
I later carefully read through FourSquare's API document, and found it says:
(Note that the request parameters are not JSON, they are standard HTTP keys and values.) All authentication is via OAuth2, which means that all requests MUST be https.
Could this be the problem that I don't have a SSL connection in my development machine?
Hi all! I am trying to connect FourSquare via Omniauth, I followed the Railscast toturial below, and change the provider into foursquare. But the return is always "invalid_credentials". I googled around and find that there's a discussion about this on GitHub(links below), but seems no conclusion yet.
Anyone has idea what went wrong?
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, "XXXXXXX","XXXXXXX"
provider :foursquare, 'XXXXXXX',
'XXXXXXX'
end
RailsCast Link
Discussion on GitHub
I have a gem which will work with omniauth for foursquare.
https://github.com/arunagw/omniauth-foursquare
try to modify your provider initializer to point to your system's certificate path ("/etc/ssl/certs" on Ubuntu)
Rails.application.config.middleware.use OmniAuth::Builder do
provider :twitter, "XXXXXXX","XXXXXXX"
provider :foursquare, 'XXXXXXX', {:client_options => {:ssl => {:ca_path => "/etc/ssl/certs"}}}
end
Your config looks fine, although you probably don't want to share your token/secret keys publicly.
Does the callback url that you used when registering your foursquare oauth consumer match the URL that you're testing with? If you used http://www.foo.com/auth/foursquare/callback when registering your consumer, but are testing on your dev environment (http://localhost:3000/..), you'll see that auth/failure error.
Here's what I did: OmniAuth Invalid Response Error