Document List API to Drive SDK and Client Login - google-drive-api

We used to have an application connector implementing the Document List Service v3 to upload documents to users account. Now that the service will be discontinued starting as of next Monday and we need to migrate to the Drive API/SDK we have the problem to migrate our current login schema .. we are unable to use the OAuth 2 protocol and we need to authenticate users with their username/password credentials.
DocumentsService myService = new DocumentsService("xxx");
myService.setUserCredentials(username, password);
The reason is that our application scans and processes documents asynchronously from MFD devices (printers) and all processing/storage job is done in a different moment on processing servers, thus the limitation that the processing service cannot ask any consens to the user.
We do the same for other online cloud storage application (e.g. Dropbox) where they allow special 'OAuth 1' schema on request for such 'enterprise' situations.
How can we do this with the new Drive API/SDK? I couldn't find anything about that in the documentation rather than the service account, also looks like not suitable.

What you need to do is request authentication from you user once. The server gives you back a refresh token. Your automated application can then use this refresh token to get a new access token. You only need to ask the user one time for authentication. Then everything can run automated.
A service account wont really work in this instance because its meant for use with an account that you the developer own not a users account

Related

How to assign multiple service account credentials to Google Cloud Functions?

I have three service accounts:
App engine default service account
Datastore service account
Alert Center API service account
My cloud functions uses Firestore in datastore mode for book keeping and invokes Alert Center API.
One can assign only one service account while deploying cloud functions.
Is there way similar to AWS where one can create multiple inline policies and assign it to default service account.
P.S. I tried creating custom service account but datastore roles are not supported. Also I do not want to store credentials in environment variables or upload credentials file with source code.
You're looking at service accounts a bit backwards.
Granted, I see how the naming can lead you in this direction. "Service" in this case doesn't refer to the service being offered, but rather to the non-human entities (i.e. apps, machines, etc - called services in this case) trying to access that offered service. From Understanding service accounts:
A service account is a special type of Google account that belongs to
your application or a virtual machine (VM), instead of to an
individual end user. Your application assumes the identity of the
service account to call Google APIs, so that the users aren't
directly involved.
So you shouldn't be looking at service accounts from the offered service perspective - i.e. Datastore or Alert Center API, but rather from their "users" perspective - your CF in this case.
That single service account assigned to a particular CF is simply identifying that CF (as opposed to some other CF, app, machine, user, etc) when accessing a certain service.
If you want that CF to be able to access a certain Google service you need to give that CF's service account the proper role(s) and/or permissions to do that.
For accessing the Datastore you'd be looking at these Permissions and Roles. If the datastore that your CFs need to access is in the same GCP project the default CF service account - which is the same as the GAE app's one from that project - already has access to the Datastore (of course, if you're OK with using the default service account).
I didn't use the Alert Center API, but apparently it uses OAuth 2.0, so you probably should go through Service accounts.

Need refresh token without using consent screen in G Suite

We are using G Suite API with our Micro service for document editing, and we have a different data center and also different db. now once user comes to my application and trying to open document first time then google give consent screen based on that i can get refresh token and access token and i store into one data center.
But problem is that if user comes from another instance which use different data center with different db and user trying to open document with old credentials then google doesn't give any consent screen so i am not getting user's refresh token.
1) So is there any way to get refresh token without using consent screen?
2) Is there any way to identify if user comes from different sub domain then i need to provide consent screen for that?
It might be possible to use the prompt=consent option to force a re-prompt for auth, even though the user has already authorized your app.
See https://developers.google.com/identity/protocols/OAuth2WebServer#creatingclient
You can identify the user's domain using the hd parameter [1] and you can request a refresh token without the consent screen after the domain admin has configured domain wide delegation by installing your application from the GSuite Marketplace [2].
[1] https://developers.google.com/identity/protocols/OpenIDConnect#hd-param
[2] https://support.google.com/a/answer/172482?hl=en
When you request an OAuth Flow (access_type=offline`), a Refresh Token is returned to your application. This only happens once (obtaining a Refresh Token). Your application is expected to save the Refresh Token for future needs.
In your use case, one of your systems completed the authentication and the user has moved to a different system. You will need to reauthenticate with prompt=consent, access_type=offline. You will not get another Refresh Token without reauthenticating.
I spent a lot of time on this issue last November. Here is a link which has lots of details on this problem.
Any application can only have one valid refresh token for a user. You can request for a new refresh token using the prompt=true&access_type=offline on the request as said by #John. But every time the previous one will become invalid.
Based on you comments on the other answers, I'm assuming creating a new micro service that returns the token to the one being used is not a possibility (that would be my recommendation)
You asked "to identify if user comes from different sub domain"...
If those applications are for end users of gmail.com accounts, you can treat them as different applications and configure different projects on the developer console.
It will be a bit of a pain when enabling new APIs, I would recommend doing that from a script that replicates to all application needed.
If your end users are from companies using GSuite, you can have your app installed as domain-wide application (either manually or from GSuite Marketplace). In that case you can use just client side authentication to get an id_token, send the token to the server and use a service account to impersonate the user in any given service without worrying about any token from them.

Project with Google APi with self user auth

I was able to create a project to connect an app to google data, for a specific account (followed Google People API)
But now I would like that each customer log in hisself to his account and manage his data.
I can' t create project in the Google API Console for each customer, my app needs to read auth from each user who will use my app and "auto" create auth to read google contact data of the logged user.
Is possible?
Could you suggest me articles about how to do?
It sounds like you are trying to do exactly what OAuth 2.0 (see the page you linked to) gives you: authenticating users. This differs from using an API key, which is only authorizing your project and has nothing to do with a user's credentials.
OAuth 2.0 combines a Client ID (associated with your Google Developers Console project) and a user's login (specific to the user who is accessing your app/site) to give you an authorization token. This token will let your app act on behalf of that user when calling that API. Just make sure to request the necessary scopes as part of the OAuth 2.0 authorization prompt given to the user.
How to give this prompt varies by environment, but many common options are listed on that link.
Note that you always use the same Client ID, so you only need one Google Developers Console project, but you are given a unique token specific to that user's login when they authorize your app, so this lets you act as any user which grants your app access to their account.

OAuth for Enterprise account

I'm creating a web app for my company that will keep a number of files in sync with the files on Box. This will be done by using a cron job running every hour.
I have the application working by setting the developer token in my account, this was done for testing whilst I was building the application.
Now this is working I want to get the authentication working so I can just leaving this running. So I'm trying to work out if there is a way I can have an API key for our enterprise account or if I will have to implement OAuth and connect one user to the application, which seems to be a bit overkill?
You should probably use one of the SDKs, which take care of refreshing the tokens for you.
Essentially what you'll need is a keystore to store the tokens. You could store the Refresh-token only. When your cron wakes up, use the refresh token to get a new access-token and refresh-token. Store the new refresh token in your keystore. Then make your API calls using the Access-token, and then go back to sleep.

Secure iOS to online database connection

I have an iPhone application that needs to collect data from an online MySQL database. I've written a PHP web service so I collect the data with JSON. The problem is that everyone can see the data if they go to the URL now. How do i secure the data transfer properly?
Thanks for your suggestions.
Typically, if you are showing data private to a particular user, then each user will generally have an account (user id and password). The app will pass the user's credentials to the server before the server will provide the user's data.
You can also do something similar using SSO integration, or OAuth (ala Facebook).
In some cases, your app may only pass the username/password on the initial call and receive a session ID, which the app passes on remaining calls. This allows the server to store session data.
Even if the data isn't private to a particular user, you can use accounts to restrict access and privileges for a publicly reachable web API.
In all of the above cases encryption such as SSL (HTTPS) must be used to protect the authentication mechanisms and data transfer.
I'm assuming your data is public for all users of your app, in other words, you don't want to implement a login mechanism for your users. If you just want to make sure you return the data only to users of your app and not to anyone who happens to enter the right URL in their browser, you will need to sign your requests, so that only requests from your app are accepted by your server.
I use a secret key that my app uses to create a hash/digest of the request which the server verifies (it knows the secret key as well). Also I make sure requests cannot be replayed if they are intercepted by adding a timestamp and a nonce. The timestamp is checked to be within 10 minutes of the server's timestamp (relaxed sync) and the nonce must be unique (server keeps the last 10 minutes of nonces). This way no-one can copy the same request, the server will just serve an error if they try.
This post explains how to sign your requests in a bit more detail:
http://www.naildrivin5.com/blog/2008/04/21/rest-security-signing-requests-with-secret-key-but-does-it-work.html