Laravel HTTP Client Bad Request on Discord API Access Token Exchange

Viewed 556

I have a laravel application setup and I'm configuring a Discord auth system. I have sent & requested authorization & recieved a confirmation code back.

When I try to exchange the code for an access token I'm receiving a 400 bad request and I'm not sure why. I'm new to laravel and can't seem to find any sort of error that may help to pin point the problem.

Controller function that discord redirects after authorization

    public function exchange(Request $request) {
      //exchange discord code for access_token
      $code = Request::get('code',false);

      $params = array(
        'grant_type' => 'authorization_code',
        'client_id' => env('CLIENT_ID'),
        'client_secret' => env('OAUTH2_CLIENT_SECRET'),
        'redirect_uri' => Request::root().'/discord/return',
        'scope' => 'identify guilds guilds.join',
        'code' => $code
      );


      $access_token = Http::withOptions([
        'debug' => true,
        'headers' => [
          'Accept' => 'application/json',
          'Content-Type' => 'application/x-www-form-urlencoded'
        ],
        'json' => $params
      ])->post('https://discordapp.com/api/oauth2/token');

      dd($access_token);
      return redirect()->route('return.discord',['token' => $access_token->access_token]);
    }

I've dumped out $params and all the data is pulling in as it should. Guzzle dumps this:

[CONNECT] [FAILURE] severity: "2" message: "HTTP/1.1 400 Bad Request " message_code: "400" [MIME_TYPE_IS] message: "application/json" [FILE_SIZE_IS] message: "Content-Length: 26" bytes_max: "26" [PROGRESS] bytes_max: "26"

I know that 400 bad request means an issue with the data being sent along, but I can't figure out what I'm doing that's not producing the correct result. The documentation states the required content type which I have set, so I'm really scratching my head here.

Any help would be much appreciated.

Here's the Discord API documentation: https://discord.com/developers/docs/topics/oauth2#authorization-code-grant

2 Answers

To anyone looking for an answer...

The "invalid grant" error is due to an issue with the Discord API and non-standard requests. I could not get the Laravel HTTP class request to work for exchanging the access token. Instead, I used native php cURL within Laravel.

As for the issue with receiving '400 bad request', that was due to using incorrect function withOptions() as oppossed to asJson()->withHeaders(). Thanks @Zachary Craig!

However, I could not use this in the end due to the problem described above.

If any others find a better solution, let me know :)!

For all who have the same problem.

The solution is to use ->asForm() before the post. This changes the handling of the data from json to form_params. This way the Discord API accepts the parameters.

return Http::asForm()->post($this->endpoint.'/oauth2/token', $data);
Related