Aleksandr Popov
Aleksandr Popov

Reputation: 520

Guzzle POST request to JWT API get Unauthorized while Postman is working

Guzzle POST request to JWT API get Unauthorized while Postman is working. Here is the code:

public function __construct()
{
    $this->client = new Client();
    $this->connect();
}

public function connect()
{
    $loginResult = $this->client->request('POST', config('api.base_uri') .'/auth/login', [
        'form_params' => [
            'email' => config('api.login'),
            'password' => config('api.password'),
        ]
    ]);

    dd(json_decode($loginResult->getBody()));

}

I got 401 Unauthorized while running this code. Credentials are passed correctly. Meanwhile in Postman it is working perfectly: While in Postman it is working perfectly

Kindly advise me what I'm doing wrong. Thanks!

UPDATE Following is controller and function this request is hitting in API side:

class AuthController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login']]);
    }

    public function login(Request $request)
    {
        $credentials = $request->only(['email', 'password']);

        if (!$token = auth('api')->attempt($credentials)) {
            return response()->json(['error' => 'Unauthorized '.$credentials['email']], 401);
        }

        return $this->respondWithToken($token);
    }
...

User does exist as it is working in Postman

UPDATE 2 I have simplified code to find that is wrong to:

Route::get('/guzzle', function () {
    $client = new Client([
        'headers' => [
            'Accept' => 'application/json'
        ]]);

    $loginResult =
        $client->request('POST', config('pics.base_uri') .'/auth/login', [
            'form_params' => [
                'email' => '****@****.com',
                'password' => '*****',
            ]
        ]);

    dd(json_decode($loginResult->getBody()));
});

And it does not work - got same error

Upvotes: 3

Views: 1878

Answers (3)

Ben Mack
Ben Mack

Reputation: 489

Run php artisan config:cache on both sites to solve this problem.

Two sites on Apache on Windows requires cached configurations. It's a known but non-documented problem. Run php artisan config:cache on both sites.

Src: https://github.com/laravel/framework/issues/21533#issuecomment-334352170

Upvotes: 0

Aleksandr Popov
Aleksandr Popov

Reputation: 520

Okay... after couple of hours and kind help of Kyslik I was able to find the clue of this issue. Actually what did helped me is debugging and looking up the error I get. Eventually I found following post (https://github.com/guzzle/guzzle/issues/1413#issuecomment-222031665) which states kind of strange thing:

Guzzle won't work at all if the same instance of PHP is used to send the Request from Guzzle, and to respond that request

I moved everything to hosting and it worked like a charm. Hope that will help someone in future.

Thanks everyone who envolved finding solution and of course to Kyslik!

Upvotes: 2

Dylan Pierce
Dylan Pierce

Reputation: 4668

Try using the json option in the Guzzle options in your POST request instead of the form_params.

public function connect()
{
    $loginResult = $this->client->request('POST', config('api.base_uri') .'/auth/login', [
        'json' => [
            'email' => config('api.login'),
            'password' => config('api.password'),
        ]
    ]);

    dd(json_decode($loginResult->getBody()));

}

form_params should be used with non-json endpoints.

More information on the json property: http://docs.guzzlephp.org/en/stable/quickstart.html#uploading-data

EDIT an example for an endpoint that accepts form-params but returns JSON, which might be what you have:

public function __construct()
{
    $this->client = new Client()
    $this->connect();
}

public function connect()
{
    $loginResult = $this->client->request('POST', config('api.base_uri') .'/auth/login', [
        'form_params' => [
            'email' => config('api.login'),
            'password' => config('api.password'),
        ]
    ]);

    dd(json_decode($loginResult->getBody()));

}

Upvotes: 0

Related Questions