Search code examples
javaandroidjsonspring-bootgoogle-identity-toolkit

POST Request to sendEmail endpoint causes org.json.JSONException: JSONObject["oobCode"] not found. after calling gitkitClient.getOobResponse(request);


I am trying to implement the "Trouble Signing In" link endpoint on my back end. I followed the steps enumerated here, and I am successfully getting a POST request via my Gitkit Widget JavaScript, but there seems to be some missing information in the request.

As soon as I call

OobResponse oobResponse = Utils.getGitkitClient().getOobResponse(request);

the following stack trace is thrown. I'll only include the first few lines for the sake of brevity.

com.google.identitytoolkit.GitkitServerException: org.json.JSONException: JSONObject["oobCode"] not found.
    at com.google.identitytoolkit.GitkitClient.getOobResponse(GitkitClient.java:411)
    at com.google.identitytoolkit.GitkitClient.getOobResponse(GitkitClient.java:372)
    at myProject.myController.sendEmail(myController.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
...

Just so you can rule this out as a possible cause of the issue, here are the contents of the utility method I use to get my GitkitClient instance:

public static GitkitClient getGitkitClient() throws FileNotFoundException {
    GitkitClient gitkitClient = GitkitClient
            .newBuilder()
            .setGoogleClientId(Constants.CLIENT_ID)
            .setServiceAccountEmail(Constants.SERVICE_ACCOUNT_EMAIL)
            .setKeyStream(new FileInputStream(Constants.SERVICE_ACCOUNT_PRIVATE_KEY_FILE_PATH))
            .setWidgetUrl(Constants.WIDGET_URL)
            .setCookieName(Constants.COOKIE_NAME)
            .build();
    return gitkitClient;
}

Here is my sendEmail endpoint method signature (I'm using Spring Boot):

@RequestMapping(value = "/sendEmail", method = RequestMethod.POST)
@ResponseBody
public void sendEmail(HttpServletRequest request, HttpServletResponse response) {

And finally, here are the contents of the HttpServletRequest that is passed into my sendEmail method:

Request Method

POST

Request Headers

Header name: host  
Header value: example.com:8080

Header name: connection  
Header value: keep-alive

Header name: content-length  
Header value: 1100

Header name: origin  
Header value: http://example.com:8080

Header name: user-agent  
Header value: Mozilla/5.0 (Linux; Android 5.0.2; HTC6500LVW Build/LRX22G; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/46.0.2490.76 Mobile Safari/537.36

Header name: content-type  
Header value: application/x-www-form-urlencoded;charset=UTF-8

Header name: accept  
Header value: */*

Header name: referer  
Header value: http://example.com:8080/myProject/callback?mode=recoverPassword&[email protected]

Header name: accept-encoding  
Header value: gzip, deflate

Header name: accept-language  
Header value: en-US

Header name: x-requested-with  
Header value: [MY APP PACKAGE NAME OMITTED]

Request Parameters

Parameter name: action  
Parameter value: resetPassword

Parameter name: email  
Parameter value: [email protected]

Parameter name: challenge  
Parameter value:

Parameter name: response  
Parameter value: 03AHJ_Vuued2d7eKM-hD[... CONTENTS OMITTED ...]G1mzdsuc8

Notice that the request parameter "challenge" is the empty string, and that there is no mention of "oobCode," as the stack trace so aptly points out.

Am I missing something here? Do I need to take an extra step in my widget endpoing? Do I need to add something more to my HTML file that houses my JavaScript widget? Any help would be greatly appreciated!


Solution

  • After talking to someone working on identity toolkit in Google, I was told that there was a misconfiguration on their end in the Identity Toolkit project. After they made some changes I can now successfully call the aforementioned getOobResponse(HttpServletRequest req) method without getting a stack trace!