简体   繁体   中英

Actions on Google - Login and Swapping Access Token for UID

I need to check that I have this right. Im building an Action on Google using the Actions-SDK. For auth, I want to use Google Sign In to keep everything relatively straight forward for the end user. My Fulfillment will sit on Firebase Functions. My OAUTH server will sit outside of Firebase.

The first thing I note is that much of the front end log in is done in JavaScript.

var provider = new firebase.auth.GoogleAuthProvider();

From here, if the user logs in, we can use:

firebase.auth().getRedirectResult().then(function(result) { } and we have access to result.user.uid

My first question here is security - because the API Key , DatabaseURL and authDomain are exposed in client side JavaScript, and using a Developer Console in Chrome, the end user has access to their ID and Token. I was wondering whether to use the uid or id token under result.user.De for some reason, but as it appears you can easily use a JWT Decoder on the internet to extract all the information so it really makes little different from a security point of view - I may as well take the uid here.

It looks like the admin side of things are available in Node.js and PHP where I can connect to database and validate tokens and create users, but I can't login. So JavaScript seems the way to go.

The next step I gather, is to post my uid back to the oauth server so we know who we're logging in as and we can tie the oauth access token/refresh token/auth code to the uid. And whether we store that link in Firebase or a MySQL database on the Oauth server, it doesn't really matter.

Then for fulfilment in Firebase Functions, we then have one userId through:

let ActionsSdkApp = require('actions-on-google').ActionsSdkApp;
const app = new ActionsSdkApp({request: request, response: response});
app.getUser().userId);

But this does not match the uid we retrieved from result... But we do have access to the AccessToken we generated on the Oauth server, so we need to exchange the Access Token for the correct uid - whether we look up from Firebase or from the OAuth MySQL Server I guess doesn't matter.

Putting it all together, does this flow all sound correct? Or is there something that could be done better? I was hoping that there was a better way of identifying the user in Firebase Functions. But it doesn't seem possible.

I think you have it mostly correct (assuming I follow everything), but a few points to note:

  1. You should not send just the UserID from the client to your server.

    As you noticed, that information is easily available to... well... anyone. This means that, unless you're careful, anyone could just send your server a UserID that they got from elsewhere and pretend to be you.

    Using the JWT Token provides a little more security. Although it contains the UserID, it also contains a signed hash of that information, so you can verify that the information is valid. It also contains an expiration, so you can reject it if it's outside the validity range. This makes it much harder for someone to just forge a UserID or re-use one that they've acquired.

    There are other precautions along these lines you should be taking as well. We can't really trust the browser, but we can narrow down the opportunity for problems.

  2. You're correct, the UserID that is sent by the Assistant has no relation at all to any other UserID anywhere. It is meant to serve as an anonymous cookie-like reference, so you know if you get the same UserID twice... the person on the other end is likely the same. It is mostly meant for simple use and not real authentication, and certainly not for authorization.

  3. Which is why the account linking procedure, your OAuth server, and handing you an auth token is so important if you do want to do authentication and authorization. You have this part correct - you need to verify that the token is valid (to help reduce the chance that somebody else isn't pretending to be the Assistant) and use it to determine the ID.

    Looking it up in a database is one option, but issuing a token as a JWT of your own is another option. Given the setup it sounds like you describe, managing that in a data store of some sort makes the most sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM