Search code examples
google-oauthactions-on-google

Account linked for Actions on Google, which field to keep in DB?


I tested Account Linking using the Simulator. Which field in originalRequest -> data -> user that I can keep? userId or accessToken?

I found that they're always regenerated when the session expires (or by toggling the "Test status: Active"), which makes it impossible to SELECT * FROM User WHERE assistant_client_id = [something].

I know that I can use accessToken to query https://www.googleapis.com/userinfo/v2/me for "real"(?) id, but doing that for every request will add extra time (and Assistant is not exactly patient).

Assuming accessToken will never be reused by others, can I do this?

  1. Store accessToken in my User table.
  2. For subsequent requests, check using accessToken.
  3. If no match, query https://www.googleapis.com/userinfo/v2/me to get id (or email) that I can use to query my table, and I update the accessToken with the latest.

Solution

  • There is currently a bug with the userId field and the Simulator that uses the sessionId under some circumstances, but this should hold true between calls in most cases on actual devices.

    If you are using Account Linking, however, this is the far better method. Keep in mind, however, that the accessToken is not an identifier. It is a temporary key to an identifier, as you note. (Sometimes it is a token that contains an identifier, but not in your case.) Access tokens are supposed to have a limited lifetime - typically an hour. There are other cases where you'll get a new accessToken as well, even in less than the timeout period.

    While you can be assured that if you see the same accessToken twice you are talking to the same user, you can't assume that the same user will always give you the same accessToken.

    Your method is good, but you'll also need to handle cleanup of old access tokens. Possibly create a timeout field, and assume that you can time them out sometime after an hour, or create a second hash from your user to the most recent accessToken and remove an accessToken when it is replaced with another one.