Authenticate with Google on the web (javascript), consume on the server (.NET) - javascript

We have a web server using Google Sign-In to authenticater and authorize for API access (Classroom). We need the sign-in part, so we're using init() and signIn(). We cannot use authorise(). Also, we're not signin in with particular scopes, as we just need identify for normal usage.
The logged-in user can enable a feature that requires offline access on behalf of his/her account to the Google Classrom API. We call grantOfflineAccess() with two scopes related to Classroom to get an authentication code, which is stored for later.
On the server side, we have a gRPC service that doesn't expose any web front-end. We're using C#/.NET with the Google API Client libraries.
I implemented an IDataStore that can respond to TokenResponse requests by either calling AuthorizationCodeFlow.ExchangeCodeForTokenAsync with the above code, or return the last TokenResponse stored in the database. When (well, "if") IDataStore.StoreAsync is called with a new version (normally after a token refresh was required), it saves it again in the database.
My problem is that ExchangeCodeForTokenAsync returns me a TokenResponse without a refresh_token. This means the access_token is only valid for 60 minutes. I would need to intercept exceptions at the service call level to call ExchangeCodeForTokenAsync again (if that works!), instead of relying on the Google API Client Library handling refreshing automatically all nicely.
What could be preventing ExchangeCodeForTokenAsync from returning me a refresh_token?
Thanks.

Well, I found the answer in this other question.
The refresh_token is only provided on the first authorization from the user. Subsequent authorizations, such as the kind you make while testing an OAuth2 integration, will not return the refresh_token again. :)
I simply removed my app from my Google account's authorized apps, and my next ExchangeCodeForTokenAsync call returned me a refresh_token.

Related

How can I provide public access to my photos

I would like to build a small js library that can read a specific album from my account and display the photos within as a slideshow.
In this guide (https://developers.google.com/photos/library/guides/get-started), to access the API we need both ClientID and Secret. Is there any way to access the API using some type of public key for read-only access? That way I (the provider of photos) don't have to login every time?
The Google Photos Library API is used via OAuth2 user authentication. All requests through the API are made on behalf of a user. Public API keys or service accounts are not supported.
OAuth tokens expire after a certain time, which is returned as part of the OAuth authentication request. You can use a refresh token to retrieve a new access token once it has expired. If you'd like to do this without explicit interactive user interaction, your application needs to be authorized for offline access. The good news is that the authentication client libraries handle this for you.
If you are using Google Sign-In (for example on Android), you can check if the user has already signed in using GoogleSignIn.getLastSignedInAccount(this), so you would not need to prompt again for access. You could also enable server-side access if you want to make these offline requests from your backend.
If you are using any of the Google OAuth client libraries, you can specify the 'offline' parameter as part of the initial sign-in request. For example in Java, you would set the access type: .setAccessType("offline") on the GoogleAuthorizationCodeFlow.Builder during creation.

Use Google Sign-in Button to authenticate users without sever

Google provides a simple sign-in button:
https://developers.google.com/identity/sign-in/web/sign-in#before_you_begin
This button calls a function, "onSignIn" on successful login as such
<div class="g-signin2" data-onsuccess="onSignIn"></div>
I am thinking about calling one of my APIs inside "onSignIn" function and generate a token and save in users' browsers. Next time when users send API requests, I plan on using these tokens in the header to verify API access.
Is this a legitimate way of using this Google widget? Or I actually have to use OAuth and such?
Frankly, you would not need the additional complexity of token generation at your API endpoints as the Google ID tokens facilitates your exact need.
Hence consider sending the user's ID token to your API and then, on the server, verify the integrity of the ID token to accredit the user authority.
Moreover, if you require association of additional information with each user session/account the same architecture can be used with a supplementary database. For a more comprehensive guide refer this article.

How to implement token based authentication in oauth2.0 process

Below is my understanding of the process of oauth2.0(using google as the oauth2.0 server)
my customer click 'login with google account' button on client side.
the browser redirect to google's login page.
my customer inputs it's credential and click 'login'.
if my customer succeeded in previous step,the browser will redirect to my server's url
(www.[myserver].com/auth/google/callback) with some extra query
data.
then my server will do some work to get some token from google and finally get my customer's information.
My question comes from the next step. I want to use token based authentication.Then I have to make my customer to store my own token in localStorage. I can't figure out how to achieve this in the 6th step(how to send a new token to client side and store it in localStorage?).
(I know that every thing will be easy if I am using cookie-based authentication. because I can just utilize 'set-cookie' in the 6th step, and the client side will be easily store the credential data in client side's cookie)
Google APIs use the OAuth 2.0 protocol for authentication and authorization. Google supports common OAuth 2.0 scenarios such as those for web server, installed, and client-side applications.
I figure out that I can use some type of template engine on my server side(just like discussed here). So I can render my template file using variable before send it to my customer.

DialogFlow sending context back after authentication?

I am having a bit of a hard time wrapping my head around how to connect to my OAuth2 Freshbooks API from my bot. Currently I have my API set up such that hitting the /auth route will take the user to the Freshbooks login page and once successfully authenticated the token is returned back to the user. After we have the token the user can get all of their invoices in my web app.
Now, when I build a DialogFlow bot, how do I go about this? What I have thought about is that the user first hits the /auth route which returns the authorization URL which the user can then open in their browser and log in...but after login, how do I return back to my bot?
After a successful login, the /callback route is called by my api with the authorization code to get the token...but this will not be returned back to the bot since it is all happening in the browser...I think.
What is the best approach for this?
Also, after getting the token from my API, should this be stored in a context in my bot?
Thanks for the help and sorry if this is a beginner question. I tried finding an answer online but I just cant wrap my head around this one.
Assuming that your OAuth service is configured correctly you don't have to worry about any of this. The procedure works roughly as follows:
Account linking is triggered via one of two ways:
If you need a linked account to fulfill a certain intent you can simply check the Sign in required box of that intent in the Google Assistant integrations page in your Dialogflow project. If you check this for all intents that are listed for invocation the user can only use your agent once they have an account linked.
The other option is to manually call the sigin helper. This can be done at any point during the conversation, i.e. it does not have to be tied to a particular intent.
When the account linking procedure starts the Google Assistant will load your login page in an in-app browser.
Once the user has authorized your client the OAuth service should (like any OAuth service) redirect the user back to the client. On the Google Assistant this happens via a redirect url of the format https://oauth-redirect.googleusercontent.com/r/<google developer project ID>.
After that Actions on Google calls your fulfillment service with the original intent (the one that triggered account linking), only this time with a valid access token for your service.
Such an access token will from now on be included in every fulfillment request your receive from Actions on Google. You do not have to store this token, you should always use the one that is send in the request.
For more details see the Implement Account Linking documentation.

Securing API calls without token

I'm building an app and an API endpoint using PHP(I know what you thinking!). My issue is that if I ask user for username and password on opening the app for the first time, since I can't store these details locally because they could be compromised. I'd send these through Post request to server then generate a token depending on whether the user is the right one. After getting response I must store this token locally right?
Yes!. there's expiration for the token. After the token is expired, I don't want to ask user for their name and password but want to access API still authenticating as that user. How will I do this?
If I use Oauth it's still the same procedure right? I should store something locally. won't that be compromised? I'm very confused.
How does other apps work. I'm sure they doing something in the background. They ask us for credentials only once and all subsequent API calls will be secured. Won't the token expire in that case or what?
Can i secure API calls without storing anything locally? I don't want API to be accessed from anywhere else but app.
Use android SharedPreferences. It should be very secure unless you deliberately expose it e.g. its accessible via an exported content provider missing the (android:exported="false") in the manifest. You can also use sqlite but there is no point of using a db table for one or two rows of data.You can also encrypt the user name and password to add one more security layer to protect rooted users.
Furthermore to protect the data in the network you should use ssl in the backend so no one can sniff the credentials.

Categories