I have nodejs server script. I would like to be access the Google API -- specifically, Google Photos. Google Photos API doesn't accept service accounts, but only oauth2. The problem is that I am using this script on a headless server (it's a remote backup script).
I am using this module to authenticate: https://www.npmjs.com/package/googleapis and would like to use this one to access the photos: https://www.npmjs.com/package/googlephotos
I created my Google App, I added the Google Photo API; I then created an Oauth authentication method, and given it the right scopes. However, right now to authenticate I am using a script I run on the terminal, which then open a page -- a modified version of this https://raw.githubusercontent.com/googleapis/google-api-nodejs-client/master/samples/oauth2.js which actually saves the access token.
I would really need the script to deal with authentication by itself. Especially since this is a personal application, and access tokens will tend to expire.
Is this impossible to do?
Related
I'm new to Python, but have previous experience writing .Net web apps.
I'm working on a website written in Python using Flask-WTF (html pages with forms and individual routes for GET and POST requests). The app makes calls against a Python Flask API that talks to a MySQL db for user authentication (user table with names and hashed passwords). Everything the user sees is handled by the web app UI, and all the logic is handled by the API.
I followed Miguel's Mega-Tutorial (https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world) to learn the basics of the Python language and how to solve a number of problems along the way.
I need my users to log in once a day (set tokens to expire every 12-24 hours or so), but then have access to the app to perform whatever actions they need. I have a Login form that grabs username/password and submits that to an API endpoint. The API verifies the user data against the db, generates JWTs (access and refresh tokens), and writes them to cookies in the response. I am able to see that the cookies are set in the web app after the initial login and verified the contents using https://jwt.io. The only thing I need from the user login after verification is the username for when a user makes a change to database entries.
The Problem: How do I actually use the info in the cookies to call subsequent #jwt_protected methods in the API? When I add the #jwt_required to a post(self) function and try to access it I'm getting back a 401 with { "msg": "Missing cookie "access_token_cookie"" } that appears to be coming from the jwt_flask_extended library. I used "access_token_cookie" as the name of the cookie for the JWT token. Are the tokens magically handled by FlaskWTF/flask_jwt_extended and I'm just using it wrong? Do I need take the info out of the cookie and add it as a header on subsequent requests? If I send the info in a header, how does the API know where to look? I have a feeling it's something minor where I'm just not connecting the obvious dots.
I'll create a standalone app to test out just the authentication features between UIs and APIs that can be shared as opposed to trying to rip out existing code minimize the existing app and api to the bare minimums in case anybody else comes across a similar problem. This might also show me what my problem really is.
The final version of the app and api will both be hosted in a Cloudfoundry environment in case that has any bearing on suggestions.
I'm currently working on a SPA with Electron that uses Azure to log the user in. For this, I'm passing the "domain_hint" query string in the authorize request to by-pass the login screen. Indeed, the user is inside a specific domain, so it gets logged in without any prompt.
I tried this connected to a VPN, and it works. However, when I disconnect from the VPN, it does not work anymore. I kind of understand why but then I'm wondering how I could work around this. I'm thinking about application such as Teams or OneDrive that ask you to login once then never ask it again, how is it working? Can I do the same with my Electron app?
So for teams, it uses modern authentication adal or msal, it's also an electron app. once the user logs in teams will store the access token in a cookie and maybe refresh token? then everytime you start it up, it will just use that. so yes, you can do something similar. you just have to store the relevant token. and grab it from storage to use
I have a Web application that currently uses OAuth2 to authenticate users using their Google accounts. The flow is quite standard: the user logs in to Google, the web app gets a callback, retrieves the user identity and stores it in the session.
Now I need to create an accompanying Chrome extension. This extension needs to access the web app underneath, so it needs to authenticate against this app. I configured my extension using the official documentation, but during experiments, I realized this is not what I need. Since it uses the OAuth2 implicit flow, it doesn't return a token that could be validated on the server side. This flow is suitable only for using Google APIs on the client side, which is not my use case. This documentation (and pretty much everything else I found on the Web) focuses on two possible cases:
We want to access Google APIs on the extension side (chrome.identity.getAuthToken()).
We want to authenticate using an alternative OAuth2 service (chrome.identity.launchWebAuthFlow()).
However, in my case, I'd like to authenticate users using Google accounts, but process the token on the server side of my Web app. I could use option 2 here, but it just doesn't "feel right" to me to create my own "non-Google authentication service" that is just a wrapper over Google authentication service, only to be able to authenticate on the server side.
Is option 2 really the only way to go, or is there any simpler way?
I also saw someone recommending using the tokeninfo endpoint to validate the token, but I find it hard to make sure that this is indeed an "official" and secure way of doing this.
To retrieve an access token that you can use on both parts of your app, the extension and the server, you should request a Google Cross-Client Access Token. This allows you to register your two apps (two client IDs) in a single project and share an access token.
This is described and discussed by Google here:
Docs: Google Identity Platform: Cross-client Identity
Video: Google Drive SDK: Cross-client authorization
The rough steps are:
You will need two clientIds, one for your extension and another for your server app
Add both clientIds to a single project
Retrieve the cross-client access token from your extension
Send it to your server via HTTPS
To do this in Chrome, it looks like you would call chrome.identity.getAuthToken() with a callback function that sends the token to your web app.
The reference says the following on chrome.identity.getAuthToken():
chrome.identity.getAuthToken(object details, function callback)
Gets an OAuth2 access token using the client ID and scopes specified in the oauth2 section of manifest.json.
and that it can take a callback function as specified as:
Called with an OAuth2 access token as specified by the manifest, or undefined if there was an error.
If you specify the callback parameter, it should be a function that looks like this:
function(string token) {...};
Ref: method-getAuthToken
I'm working on a project to connect Google Apps (Contacts, Gmail, etc.) to our own private software.
I'd like to use Hapi.js in order to achieve this, but since I have no expertise in the matter (OAuth, Google, etc) I found it to be quite challenging.
I wonder if it's posible to use Hapijs and Bell to handle the "ask permission" flow, and once authorized save the credentials to long-term uses.
Also, is it possible to use Bell to handle token refresh and consume api? (like requesting http://www.google.com/m8/feeds/contacts/default/full)
In the documentation for Bell, there's an example for twitter, basically you need to change the provider to Google: https://www.npmjs.com/package/bell
When you request access, you can add the parameter access_type with a value of offline. The server will response also with a refresh token that you can use in further requests to the API's without asking for the user credentials again.
You won't be able to store the actual user's credentials since it wouldn't be secure.
You can use the Google OAuth playground to learn more about the authentication process, here is the link https://developers.google.com/oauthplayground/
Here you can find more information and examples of using node.js and the Google API's
How would I authenticate with Firebase in a chrome extension? I need to specify the allowed domain list in the Forge. Chrome domain for the extension is just a big hash-like string.
I did read this: authClient.login problems
But the hashed based domain of a chrome extension is not being accepted in the Firebase forge. Is there another way to go about it? Currently am just reading the cookie firebaseSessionKey to just assume that I am logged in. But surely that can't be as secure as letting Firebase validate this session key.
As Rob points out, authentication cannot work in an environment that does not enforce origin restrictions. The fundamental problem here is that any authentication provider (Facebook, Twitter, Persona, or your own service) cannot issue an identity to a browser - i.e. it is meaningless to use Facebook to login to your browser (or extension).
The F1 add-on for Firefox ran into a similar problem (http://f1.mozillamessaging.com/) - where you would authorize F1 to post on twitter/facebook on your behalf. The extension had a website to along with it, from where you would serve the login page and proceed as you would normally in a web page. You'll need some code to communicate between the web page and your extension, chrome provides the tools necessary.
I would recommend the same approach - create a web page on a real domain (Github pages is awesome for this) to go along with your extension. This means your extension can't work offline, but neither can your login or writing to Firebase!
This will work using Google Plus Login Flow which I believe is the only one that allows cross authentication so the scopes are Google Plus Login.
"www[dot]googleapis[dot]com/auth/plus.login"
So what is happening here is you will get the access_token from the extension which you will be sending to firebase with the request using authwihtoauthtoken specifying google as a provider along with the access_token acquired from chrome.identity.getAuthToken()!
https://www.firebase.com/docs/web/api/firebase/authwithoauthtoken.html
Now the fact is that this access token could be issued by any other app, so we need to make sure that it is valid and has been issued for our app, basically we need to know there isn't man in the middle trying to access our database.
This verification is being made by the firebase.
They will check if this token belongs to the same application as the token has been issued to.
So you will need to create another set of credentials under the same application in the google developers console as for your extension. We will be basically doing the same thing as if we were to do it for our webpage but we will be inserting this new set of credentials to firebase's google oAuth in their security section.
They will do this check for us there. They will verify with google if the token is issued to the same app.
That's it.
Background Information.
https://developers.google.com/identity/protocols/OAuth2UserAgent#validatetoken
Use case
Sending ID tokens with requests that need to be authenticated. For example, if you need to pass data to your server and you want to ensure that particular data came from a specific user.
When to verify the access
All tokens need to be verified on your server unless you know that they came directly from Google. Any token that you receive from your client apps must be verified.
Google has a tutorial how to do this for python found at:
"github[dot]com/googleplus/gplus-verifytoken-python"
So basically what is happening here is; instead you doing to verification from on your server, firebase does this verification for you when you enter the CLIENT_ID and APP_SECRET into the firebase and enable the Google Authentication.
The way to do this correctly is a combination or same style of verifying to whom the client_secret was issued. Chrome will give you a access_token and then this access_token will be checked on the firebase's backend.