3

I followed this guide in order to create account linking in my app https://developers.google.com/actions/identity/google-sign-in#json

I'm able to verify the user's jwt decoder and send back a response that the user is authorised. Then, according to the guide, in the next request, I should get the user's profile payload (user.profile.payload in the json structure) but It's missing from the next request. More than that, I get the tokenId for jwt verification again. I think that what i miss here is in the possibleIntent object but I'm not sure, as I didn't see any documentation for that, because I work with asp.net server. There are SDKs with documentation for java and nodeJS only

this is the request provided for the sign in the contain the tokenId

{
  "user": {
    "locale": "en-US",
    "lastSeen": "2019-07-11T14:18:10Z",
    "idToken": "<tokenId>",
    "userVerificationStatus": "VERIFIED"
  },
  "conversation": {
    "conversationId": "ABwppHH9uZfcKj6pS6A6wItKC1dOXuZJ5oFYt2Og7cqrElSQYC9bv-aV7iQ5FDYaJPp-fa7tQNhc2yS0fw3QBu-M",
    "type": "ACTIVE",
    "conversationToken": "e0e78f40-a207-49c2-9050-50c6ed526c24"
  },
  "inputs": [
    {
      "intent": "actions.intent.SIGN_IN",
      "rawInputs": [
        {
          "inputType": "KEYBOARD"
        }
      ],
      "arguments": [
        {
          "name": "SIGN_IN",
          "extension": {
            "@type": "type.googleapis.com/google.actions.v2.SignInValue",
            "status": "OK"
          }
        },
        {
          "name": "text"
        }
      ]
    }
  ],
  "surface": {
    "capabilities": [
      {
        "name": "actions.capability.SCREEN_OUTPUT"
      },
      {
        "name": "actions.capability.ACCOUNT_LINKING"
      },
      {
        "name": "actions.capability.AUDIO_OUTPUT"
      },
      {
        "name": "actions.capability.MEDIA_RESPONSE_AUDIO"
      },
      {
        "name": "actions.capability.WEB_BROWSER"
      }
    ]
  },
  "isInSandbox": true,
  "requestType": "SIMULATOR"
}

this is the response that i provide after verifying the user. I tried it with both intents actions.intent.TEXT and actions.intent.SIGN_IN but with no success. the next request is provided with the user.idToken property again instead of the user.profile (that should contain the payload)

{
  "conversationToken": "b09d915e-6df9-496d-acde-b76858cd95b4",
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "Hi",
                "displayText": "Hi"
              }
            }
          ],
          "suggestions": []
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.TEXT",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.SignInValue",
            "status": "OK"
          }
        }
      ]
    }
  ]
}
Prisoner
  • 49,922
  • 7
  • 53
  • 105
lior.mor
  • 158
  • 1
  • 9

1 Answers1

3

The user.profile attribute you're talking about is something that is provided via the actions-on-google library for JavaScript. It isn't in the JSON that you will receive. But...

You don't need it because the basic profile information (name, email, and Google ID) is encoded in the user.idToken. That string, which will be sent to you for every request, is just a JWT token which you can verify and decode. The profile will be in the "payload" section.

I don't know c#, but https://jwt.io/ contains a list of libraries which can decode the JWT string for you so you can read the "payload".

Keep in mind that you don't need to verify the token each time (although if you do it right, this shouldn't be expensive), but that you can decode it to get the information that you're looking for.

If you don't want to decode it, you can decode it when you first verify it, get the information you need, and store that information in the userStorage string (assuming you don't expect it to change).

Prisoner
  • 49,922
  • 7
  • 53
  • 105
  • thanks! i know that i can decode it every time but isn't it a bit awkward decoding again and again in each request of the session? shouldn't the token verifying be one time only? – lior.mor Jul 12 '19 at 14:44
  • I don't think it is "awkward", but I've updated my answer to address your questions. – Prisoner Jul 12 '19 at 15:33
  • ok tnx. i thought that google takes care of pushing the payload in each request after you send a response that the token is verified. indeed not 'expensive' to decode however seems redundant. assuming that the token stays the same might be unsafe – lior.mor Jul 12 '19 at 16:37
  • If all you need is the user ID, then it is a safe assumption. If you are using their name, then it isn't. Depends on your needs. Keep in mind that the token *will* change - since it will be signed with a different key as the keys rotate. But the payload content should change fairly infrequently. – Prisoner Jul 12 '19 at 17:04
  • As for redundant... wouldn't sending both the idToken and the profile information every time be redundant? {: – Prisoner Jul 12 '19 at 17:04
  • what i meant is that after verifying the user i expected google to provide only user's payload, without the token – lior.mor Jul 14 '19 at 05:29