Identity API Scope Approval UI preventing OAuth Verification - google-chrome

I have a chrome extension I am trying to go through OAuth verification with. The requirement is that I do a screen recording displaying the URL with the Client ID in it. When going through authentication an application which appears to be part of the Chrome package called Identity API Scope Approval UI pops up for the authentication. The OAuth Verification team continues to tell me I need to submit with a URL bar. How do I get the URL back?
This line of code is requesting the token.
chrome.identity.getAuthToken({ interactive: true }, function (token) {})

The Identity API Scope Approval UI can be right clicked and the url seen at the top. Maximize the window and you should be able to get a view of the client ID. I also have displayed the HTML with the client ID for good measure.

Related

OAuth Verification using chrome.identity.getAuthToken

I have an extension that is working perfectly correctly using chrome.identity.getAuthToken (https://developer.chrome.com/apps/identity#method-getAuthToken). I need to submit the oAuth consent screen for verification as it uses a restricted scope.
I received an email from the Google OAuth certification team about the creating a video showing the step by step of the auth procedure, all fine except for one step that states I need to show the:
URL bar of the OAuth Consent Screen shows the Client ID containing the
project_number fully displayed (Note: this is not required for native
Android and iOS apps)
I am stuck here as the oAuth Indentiy API providor used by chrome.identity.getAuthToken shows the consent screen in a window without any URL bar! I can't see any options to change this or show it....
What should I do?
Refactor the auth to a popup rather than using the
chrome.identity.getAuthToken
Try submitting without and see if it goes through?
Thanks for your advice.
So, I replied to the OAuth verification team an explain that chrome.identity verification screen does not show the URL bar and received an acceptance less than 24 hours later.
My recommendation to anybody requesting verification and worried, is just go for it and explain where you cannot meet what they have asked.
Thanks

Receive authentication response data from a non-Google service via a Gmail add-on

I'm building a Gmail add-on with 2 steps:
Authorization with Gmail account.
Authenticate to access my service.
Example: The same as Trello add-on:
When I click the button to login, a login form appears like this:
I want to receive data response after sign-in. I've read ActionResponse documentation, but can not find a solution.
How can I receive the data response?
I believe , you are trying to authorize a custom service.
In order to authorize a custom service like trello, you will have to configure oAuth for it.
Create an oAuth service at gmail add-on to request access to trello.
Once the user completes the oAuth flow, you can use the oAuth service to get the access token. Use this token to access the endpoints whenever required.
Refer example
Edit 1:
Action Response
The usage is as follows:
//action
var onTestBtnClick = CardService.newAction().setFunctionName('onTestBtnClick');
//Button
var testBtn = CardService.newTextButton().setText('test').setOnClickAction(onTestBtnClick);
//action handler
function onTestBtnClick(){
//do some action and finally open google.com
return CardService.newActionResponseBuilder()
.setOpenLink(CardService.newOpenLink()
.setUrl("https://www.google.com"))
.build();
}
You need to setup a separate authentication page for your server(3rd party service). The user has to go through the auth process on your page. Once the user successfully authenticates with your page you need to redirect him to the redirect_uri which is passed to your page from the add-on as an url parameter. Script at the redirect_uri will hit your token url endpoint, which you specify when initiating add-ons auth service. If your token url endpoint returns a valid response, authcallback function in your add-on code is triggered which caches the session and lets the user proceed with using your add-on.
Here's a diagram of the overall flow:
Check out this library Google provides to make the implementation easier.
Also checkout my post which goes into more detail on how to connect your 3rd party services to Gmail add-on
Please see this documentation https://isamatov.com/gmail-add-on-connect-non-google-service/
This will provide you the your ans.
You need to the login page url in
setAuthorizationBaseUrl('https://domain/login.php')
The response which you want to receive is need to set in below URL
setTokenUrl('https://domain/response.php')
function getService() {
return OAuth2.createService('Demo Auth')
.setAuthorizationBaseUrl('https://domain/json.php')
.setTokenUrl('https://domain/token.php')
}

How to Sign Into Specific Google Drive Account through Javascript Google Drive API

I am trying to run a script off of my Google Drive through the Javascript Google Drive API. This works fine, but only if I sign into my account on the popup that opens. I wish to sign into the same account every time and so was wondering if there was any way to automate the login of this so as to bypass users having to enter in that login information.
In short, you would have login at least once, everytime after the Google Identity Provider JSON Web Token expires. I am not sure how long this would be with the Goolge Drive API, but typically these tokens may be valid for anywhere from a single request to days long.
Here is the Documentation for the Google API OAuth2
https://developers.google.com/identity/protocols/OAuth2
Refresh the access token, if necessary.
Access tokens have limited lifetimes. If your application needs access
to a Google API beyond the lifetime of a single access token, it can
obtain a refresh token. A refresh token allows your application to
obtain new access tokens.
Note: Save refresh tokens in secure long-term storage and continue to
use them as long as they remain valid. Limits apply to the number of
refresh tokens that are issued per client-user combination, and per
user across all clients, and these limits are different. If your
application requests enough refresh tokens to go over one of the
limits, older refresh tokens stop working.
Google has provided a quickstart guide for implementing a user sign via Google Apis. Google uses the OAuth2 protocol in which you must register with Google as a Client application. Once registered as a Client application, you will be issued a Client ID, which you typically provide to your application in some form of application initialization.
Here is a link to their quickstart guide, which will help you get started:
https://developers.google.com/drive/v3/web/quickstart/js
Note that this is a basic example that does not demonstrate how you may approach persisting a JSON Web Token so that the user does not have to login on every request. I outline a simple approach of managing Authentication in JavaScript and Angular to get you moving in the right direction, but incomplete, direction.
For example, in Angular:
// Configures the required variables before Running an Instance of the App
angular.module("yourModuleName").config(configureApp);
AND
// Executed when the App Instance launches, allowing you to connect to Google APIs when the App starts
angular.module("yourModuleName").run(runApp);
Where configureApp and runApp are JS functions that handle application initialization in the AngularJS Framework. The code in the follow example would retrieve the Apps Google Client ID from their own App's REST API. This is just an example of where you could retrieve these credentials from storage, but most likely is not the most secure example:
var configureApp = function($http,$window) {
// Setup your CLIENT ID from your own REST API (or any other mechanism you may choose)
var httpPromise = $http.get("http://myApp.myDomain.com/config/googleClient");
// Handle the Response from the above GET Request
httpPromise.then(
// Handle Success
function(response) {
// Store the CLIENT ID in local storage for example
$window.localStorage.setItem("GOOGLE_API_CLIENT_ID", response.data.clientId);
// Setup the App Wide variables for Google API
// Client ID and API key from the Developer Console
var CLIENT_ID = response.data.clientId;
// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"];
// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';
// Do more initialization configuration
};
var runApp = function() {
// Initialize the API
gapi.client.init({
discoveryDocs: DISCOVERY_DOCS,
clientId: CLIENT_ID,
scope: SCOPES
}).then(function () {
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// Handle the initial sign-in state.
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
signoutButton.onclick = handleSignoutClick;
});
}
Which function to use with Angular would depend on the desired app lifecycle you need to target in an Angularjs app. This approach can be applied in other JS frameworks like React and Backbone.
To highlight another perspective from the documentation, updateSigninStatus would be a great place to capture the JSON Web Token returned by Google's Authorization request at which point you could store this token in the browser's window.localStorage for re-use.
You then could reuse the token whenever the Google API requires authentication. Tokens typically have an expiration. Until the token expires, you would be able to prevent the API from displaying a login modal.
This does mean you would still have to manage the logic behind the Authorization process using this approach, monitoring any response from Google requesting a token refresh or re-authentication.
Auth0 is a great Authentication and Authorization plugin available in many languages for connecting with Google and many other OAuth2 Identity Providers. The Google Drive API uses their own Identity Provider Service to confirm the Identity of your apps users in tandem with your registered app's Client ID.
Here are links that I found when implementing Authorization for a project that required me to implement Authorization using the Google Identity Provider:
https://jwt.io/
https://auth0.com/
Best practices for authentication and authorization in Angular without breaking RESTful principles?
https://thinkster.io/tutorials/angularjs-jwt-auth
You are saying that all users login to the same Google account?
In that case you have 2 options.
1/ write a server application that has a stored refresh token. Create an endpoint that allows an authenticated user to request an access token.
2/ embed a refresh token in your JavaScript, but make sure that only authenticated users can load the JS

box.com api OAuth authentication

Either I'm dense, or the docs assume I already know what they're telling me, but I need some clarification on doing authentication for a box.com app. I really don't understand whate's going on. As I read it:
the app running on the user's machine sends a request to Box, including all the little secrets (Which aren't all that secret any more if the user knows how to read the code).
The user is directed to the Box login page, which then sends the user to my server (with no page specified) attaching an authentication code.
The app somehow magically gets that code back from my server and sends a request to Box for the access token.
Box sends the access token to my server?
The app again magically gets the access token from my server and sends its APT requests.
Obviously I got lost somewhere.
And, why do I have to have a server involved in the process? The article on making a JavaScript app refers to a direct request for a token. Is there documentation on that somewhere?
You register your application on Box
After registration you receive clientId and clientSecret once on Box website
You hardcode your credentials somewhere in your application
First time your application needs to access Box API it should redirect user to https://www.box.com/api/oauth2/authorize, specifying your clientId, clientSecret and redirectURI as parameters. About redirectURI see below.
The box.com website opens. User enters his own credentials in the web form on box.com
User allows your application to access his files via API on the box.com website
Box redirects user back to you application using redirectURI specified before. One of the parameters to this request is "code". This is a very short-lived (30 seconds) access code that is only aligable for obtaining real access token.
During next 30 seconds your application should make another call to Box API to next URL: https://www.box.com/api/oauth2/token, specifying the previously obtained code. If everything was correct, your application receives an access_token, a refresh_token and "expires" values.
Now your application can make requests to Box API, specifying access_token every time
access_token expires in number of seconds, specified in "expires" field. It should be about 3600 seconds or 1 hour. Each time your application sees that access_token has expired, it should make another request to Box with the refresh_token and obtain a fresh access_token for another 1 hour.
refresh_token itself expires in 14 days
Note: if you develop a desktop application, then you should open browser for user on the step 4, redirectURI should be something like http://127.0.0.1:8080/Callback and you should run a small webserver just to catch the redirect with the code as in step 7.
Box requires that you specify a redirect_uri in your application's profile, and it must be an HTTPS URL.
As a result, it is not possible to use box with what google's oauth2 documentation calls "Client Side" or "Installed" applications, only "Web Server Applications" are allowed. Web Server applications do not have the secret leaking problem, because only the server knows the secret. You can pass the access token from your server to javascript on the client after
the oauth transaction is complete, if you want the client to make api requests directly.
In your question you are not totally clear in what you are actually trying to produce.
I however suspect that you are trying to write a client application what needs to authenticate to box using the OAUTH2 solution they have delivered in API V2.
If this is for an IPhone for example BOX has a great example of how to handle it.
In a WinForm application you would need to capture the resulting code sent back by box in the browser1.isnavigating event.
Windows console application you register a custom URI registration to collect the code.
Neither of these need to be registered in the API developers Application on box as you would pass the redirect required in the request to box.
If this does not point you in the right direction and your writing a .NET app then post again and I will try to clarify a little more.
Box requires some form user interaction which is short sighted in my opinion but try a web service that simulates a user interaction which then you can save/pass the token to your application to sync up with the Box "Cloud".

appNotInstalled when the refresh token is missing?

Lately I've been noticing a strange behavior when trying to access Drive specific actions. The use case is as follows:
the user installs the Chrome Store application
the user launches the application, we get a refresh token for the email and the profile scopes
the user wants to export a document into Google Drive
error message 403: appNotInstalled is returned
If the user goes to Google Drive and opens a file from there using our application, they are redirected to a new authorization dialog that asks for the email, profile, drive scopes. After the user grants access, the initial export also works fine. My assumption is that the initial refresh token that we had was no longer valid, even though exchanging it for an access token worked and the refresh tokens don't expire.
Shouldn't we receive a more descriptive error message in this case that would suggest that we simply have to redirect the user to the authentication dialog instead of the Chrome Store listing?
The issue might be that you are using a different client id/secret than the one you registered for the Drive SDK.
A quick test would be to:
revoke all granted tokens for your application on your test account
visit your application from the New Tab Page, it should redirect you to the authorization page: copy the URL you generated (do not approve).
visit your application from Drive, it should redirect you to the authorization page: copy the URL (do not approve).
Make sure the 2 URLs are identical (they should be), especially look for similarities in the scope and client_id query parameters.