Search code examples
phpcurlgoogle-apigoogle-oauthgoogle-api-php-client

400 error code when using Google oAuth2 server-side authentication


In my PHP-based application, I've been using the Google oAuth 2 server-side flow for several years, and it has always worked flawlessly, until recently. I've been reading on any possible breaking API changes, but can't find any. Most questions having similar issues are several years old, so I'm asking a new question. It is particularly strange that this stopped working without any change on my end.

Below details are from my dev environment, but I'm getting similar results on production. This is the URL I use for getting the permission (not sure what the correct terminology is):

https://accounts.google.com/o/oauth2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=%2Fprofile
&redirect_uri=http%3A%2F%2Fwww.jungledragon.org%2Fapps%2Fjd4%2Fsignin%2Fgoogle%2Fcallback
&response_type=code
&client_id=652476484487.apps.googleusercontent.com
&approval_prompt=auto

This seems to work correctly. If not given already, the user indeed sees the Google screen to grant access. If the user then approves proceeds, they are redirected back to my application given the callback URL.

With permission given, the next goal is to get some user data. For this, the following code is used:

        // get values from the callback URL
        parse_str($_SERVER['QUERY_STRING'],$_GET);
        $code = $_GET['code'];
        $error = $_GET['error'];
        $state = $_GET['state'];

        // an error reason is returned, something went wrong
        if ($error_reason) { return false; }

        // our app is recognized, get access token by doing a post to the Google oAuth service
        $url = 'https://accounts.google.com//o/oauth2/token';
        $data = 
        "code=" . urlencode($code) . 
        "&client_id=" . $this->CI->config->item('pd_oauth_google_clientid') . 
        "&client_secret=" . $this->CI->config->item('pd_oauth_google_clientsecret') . 
        "&redirect_uri=" . urlencode($this->CI->config->item('pd_oauth_google_callbackurl')) . 
        "&grant_type=authorization_code";

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);

        // check the result. anything but a 200 return code is an error
        $info = curl_getinfo($ch,CURLINFO_HTTP_CODE);
        if ($info!=200) { return false; }

As you can see, a CURL POST request is created with several parameters. None of the param values have changed and this has worked for years, yet now stopped working, for unknown reasons.

The particular problem is that the response of the post is the Google Error 404 (Not Found)!! page. This doesn't give me any meaningful info on what could be wrong.

Help is greatly appreciated, as this issue blocks all users on my production site that log in via Google authentication.


Solution

  • https://accounts.google.com//o/oauth2/token

    will result in a 404

    https://accounts.google.com/o/oauth2/token

    will result in

    {
      "error" : "invalid_request"
    }
    

    No idea why your code worked for the last year you have an extra / in there