I am using oauth to access different services provided by google.I am able to generate token per service basis. But I want to generate single token to use multiple services from google.
Can anyone tell me the solution for this?
https://developers.google.com/accounts/docs/OAuth2
As per the Google OAuth2 docs, it is possible to do this by setting multiple scopes, but be warned, it isn't a happy experience.
When making your request, set the scope parameter to multiple scopes, each separated by a single space.
Example: "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email https://www.google.com/m8/feeds"
You can currently find a list of scopes here: https://developers.google.com/gdata/faq
Unfortunately, API access is not additive, meaning, if you ask for an access token for the Google Contacts API, then later on as the same application ask for an access token for the Google Profile API, you will end up with two access tokens, and neither can be used to access the other API. Facebook at least has the decency to give you back a single access token that grants access to all the permissions granted so far.
Because of this, you are left having to keep track of multiple access tokens (a horrible nightmare, given they expire very quickly), or ask for all of your permissions up-front, which is a user experience disaster.
Fragmented and disparate, the Google APIs are currently setup to fail if you want to do tight, multi-faceted integration.
Related
I currently have a backend running on AWS Lambda and I'm using DynamoDB as a database. In Dynamo, there is a list of users and each user has specific permissions as to what routes they have access to through the API. There is no issue here.
I have not built the front end yet, but I will be logging in users using Google Auth, more specifically with the react-google-login component.
My question is: Once a user is logged in to the site, should I trust the JWT from Google (after verifying its legitimacy
here with the Google API) which returns the user information (Name, Email), lookup the user item inside of Dynamo to retrieve their permissions, and then serve their request?
This seems like the logical thing to do but I was looking for some confirmation. My one worry is that someone could use a supervisors name & email to authorize a request but if the lambda must accept a JWT created by Google as entry, I believe this problem is solved correct?
I have API Keys as well for every user for some external functionality, but I have that covered since it's just a Dynamo call away. My only concern is with the front end requests to Lambda since I do not want to roll my own auth/jwt.
Here is what I was envisioning.
Thank you!
Normally you should use access tokens for that purpose. The ID token should be meant only to authenticate the user, and the access token should be used to authorize access.
The best scenario would be to have a separate Authorization Server which could issue access tokens, and there are some open source solutions out there which you can use.
If you really don't want to setup your own AS then you could follow the scenario you outlined - the part with verifying JWT from Google and checking permissions in the DynamoDB is what the Authorization Server would normally do to issue an access token.
Just remember to thoroughly validate the incoming JWT - not only the signature with Google, but also check if that is a token created for your client / audience, etc. Otherwise someone could take a Google ID token JWT from their client and gain access to your API. This article lists best security practices when working with JWTs.
Also remember that ID tokens might have short expiration times and there are no means of automatically refreshing them (like you can do it with a refresh token in case of an access token), so you might end up having to reauthenticate quite often.
At work we have never used 3rd party Auth solutions and I'm trying to inform myself of how they work for my personal projects. Getting the response is easy enough, but feel a bit lost on what to do after I get the response back. Am I supposed to send the auth token to the backend so it can be verified then trigger my app's login process for the given e-mail address/username? Logging them in essentially without a password?
There's two basic use cases for OAuth 2.0 which will determine what you do after the user is authorized. Your use case can also determine which OAuth 2.0 permission scopes you request the user to authorize your app for.
1. Single Sign-on
A simple use case for using a 3rd party OAuth solution is to leverage the 3rd party to perform authentication. Two reasons for this include:
Your users may wish the convenience of logging in with another provider (like Google, Facebook, Twitter, etc.), one where he or she may already have an active session.
You may not wish to implement your own login / authentication / password reset process.
Either way, a common way to implement this is to make an API request using the token to retrieve the user's email address after a successful authentication, which you then map to your own user database to establish an authenticated session for your service. Since you only need to retrieve the user's email address and minimal other information (e.g. name) in this use case, you can ask for a minimal set of scopes.
I do this in my oauth2more library where after receiving a token, I have a generic interface to load a user data which I convert to a SCIM user object. Because I've abstracted the code to retrieve user info in this manner, it's easy to support SSO across mulitple auth providers.
2. Using Service Features
A slightly different use case is that you want the user to authorize your app so you can make commands on behalf of the user via API. In this case, you will use the token to call more general APIs to accomplish your goals. A caveat is that you will need to make sure you ask for the proper permissions when asking the user to authorize your app.
As an example, one thing I've done is ask the user to sign in with Google so I can then make API calls to create and edit Google Sheets and Google Slides using APIs on their behalf.
I want to use Oauth2 personally because I am trying to use the google APIs. I do not have intention of making an app for others. But the Credentials for Oauth2 require a authorized domain with certain pages already created.
So how can I use OAuth2 without the domains? Or is there another way to accept google apis without this process?
I looked into Oauth playground but the tokens get revoked within 24 hours. I need something where I do not constantly need to get new tokens or where I can automatically generate tokens.
I am using django-allauth and django-rest-auth for iOS mobile app back-end. I am new to Django Rest Framework and to mentioned ones in particular. Those are great for access token based authorization. As you know when after successful log in user receives an access token and when logged out the access token is deleted. But, in case of multiple devices I assume that user will be logged out from all devices. Is there a way to create access token for each device and use these access tokens for authorization?
When you are dealing with authentication between your own API, your client, and a third-party API, you never want to expose the token for the third-party application to your clients. I've covered this in the past on Stack Overflow for python-social-auth, which I recommend looking at for django-allauth as well.
You have said you are using django-rest-auth, which maintains a single token per user that is shared across multiple clients. This is very similar to the TokenAuthentication that Django REST Framework provides, and it carries many of the same drawbacks. Because all clients share the same authentication token for a user, all clients will be affected if the token has to be revoked for any reason. Even worse, django-rest-auth allows users to explicitly "log out", which immediately revokes the token for everyone. This works well if only one or two clients will be using your API, and they can handle tokens mysteriously disappearing, but it does not work well for anything larger. It also does not support multiple tokens for users, which is what you are looking for.
I typically recommend for APIs to use a token-based authentication like OAuth, and django-oauth-toolkit tends to be the recommended one for Django REST Framework. This will allow you to essentially proxy requests between the third party and your client, while keeping tokens for users unique to the client. As the tokens are unique to the client, you will not need to worry about a token being revoked or expiring for one client affecting another client, as the tokens will be independent of each other.
OAuth is used by many of the "big names" out there, like Stack Exchange, Google, and Facebook. While it does not directly support the concept of "logging out", it is usually recommended that you create your own pages for users of your application to revoke tokens for applications, so they have control over who can and can't access the API on their behalf.
I have my OAuth process working well, I have an application that requires Google Adwords and Google Analytics access tokens. For whatever reason, Google has made these separate in terms of acquiring OAuth tokens. I know there is limited capability of using the Analytics tokens to access an Adwords account, but this requires the user to actively connect their two accounts, and even then access is limited. I have the user redirected away to authenticate with Google and when they come back I have their token and token secret.
One main functionality I need to impose is the user must be able to authenticate one account, and just use that. Or authenticate both accounts (analytics and adwords) and be able to use the two in tandem, with the tokens stored separately.
My main question is this: how can I figure out which oauth token has been returned? Currently, I have the oauth process located on two separate pages (two seperate callback urls, one for analytics and one for adwords), but I want to make them on the same page, and I've realized that they both return oauth_token & oauth_token_secret. Has anybody come across this before? How did you decipher between the two when the callbacks are located on the same page?
What's the best practice for this situation? It's not the end of the world, if I have to authenticate the user for each service on two separate pages, but would like to know that I have tried to implement something like this :)
Thanks!
Generally you should have a separate callback page for each service. It's simpler and easier to keep the tokens separate.