Search code examples
phplaravelhttpguzzlelaravel-livewire

Laravel Guzzle Post Request returns 403 - Forbidden response


I am using the following code: obviously, there is something that I am missing, because the post request in Guzzle returns a 403 - Forbidden response, just can't figure out why.

Sending this request in Postman app returns values as expected. The signature is entered with the signature pad package, and it correctly binds to the $this->currentVariables['signature'], and a file is saved perfectly in the storage folder.

But I am just unable to send this file to the API inside the file_variables parameter. What am I doing wrong or please correct the following livewire controller code:

public function next()
    {
        $this->header = [

            'Accept'     => 'application/json',
            'X-API-KEY' => $this->user->api_key,
            'Content-Type' => 'multipart/form-data',
        ];

        $body = [
            [
                'name' => 'u',
                'contents' => $this->task->action->systask,
            ],
            [
                'name' => 'session',
                'contents' => $this->task->session,
            ],
            [
                'name' => 'name',
                'contents' => $this->currentQ['qName'],
            ],
        ];

        if (isset($this->currentQ['qType'])) {
            if ($this->currentQ['qType'] == 'signature') {
                //upload signature file
                Storage::disk("docs")->put('signatures/signature' . $this->user->da_id . '.png', base64_decode(Str::of($this->currentVariables[html_entity_decode($this->currentQFields[0]['variable_name'])])->after(',')));

                $sign = fopen(storage_path('docs/signatures/signature' . $this->user->da_id . '.png'), 'r');
                array_push(
                    $body,
                    [
                        'name' => 'file_variables',
                        'contents' => json_encode([$this->currentQFields[0]['variable_name'] => $this->currentQFields[0]['variable_name']])
                    ],
                    [
                        'name' => 'signature1',
                        'contents' => $sign,
                    ],
                );
                if (isset($this->currentVariables[html_entity_decode($this->currentQFields[0]['variable_name'])])) {
                    unset($this->currentVariables[html_entity_decode($this->currentQFields[0]['variable_name'])]);
                }
            } else {
                array_push(
                    $body,
                    [
                        'name' => 'variables',
                        'contents' => json_encode($this->currentVariables),
                    ],
                );
            }
        }
        $api_url = config('hrda.base_uri') . config('hrda.resume_session');
        $client = new Client();
        try {
            $response = $client->request('POST', $api_url, [
                    ['headers' => $this->header],
                    'multipart' => $body,
                ]);
        } catch (RequestException $e) {
            return back()->with('error', $e->getMessage());
        }

        // ...
    }

The signature is saved perfectly in the storage folder as a png image. I have tried to send it with file_get_contents fopen and base64 encoded and decoded, nothing seems to be working. PHP v.8.2.0 / Laravel 10.6.2

The API allows my IP address, since Postman is able to access and return values, that seems to not be the problem.

** Postman data **

**Request Headers**
    *x-api-key*     oNV9KwVRCSVG5asdWEXwlEG2nf2
    *Accep*t            application/json

**Bodyform-data**
    *Session*           b2QWUlCEOWJLr7dnLLlgnGzpwaIiZ9Ax
    *u*                 frontend.yml
    *signature* 
 C:\users/xyz/storage/userDocs/signatures/signature7.png
    *name*          Question_2

Solution

  • Resolved this. Just had to remove the array brackets in the request call:

    $response = $client->request('POST', $api_url, [
                    ['headers' => $this->header],
                    'multipart' => $body,
                ]);
    

    -->

    $response = $client->request('POST', $api_url, [
                        'headers' => $this->header,
                        'multipart' => $body,
                    ]);