Passport: expectsJson is not working

Created on 22 Sep 2016  路  3Comments  路  Source: laravel/passport

Hi, the first thank to the great package. I have a problem, when I change token on postman. The response return WEB login, and function expectsJson in unauthenticated Exception Handler is not working.
Please help me,
Thank you!
screen shot 2016-09-22 at 12 03 04 pm

Most helpful comment

Hey @duccanh0022,

It is working properly if you take a deep dive into the method. What expectsJson() does is first check if the request is AJAX and !PJAX. It checks whether the request is AJAX by the existence of the X-Requested-With header and by checking if it's value is XMLHttpRequest. If that is true, that first part will pass. The second part, is !PJAX, that is done by checking for the X-PJAX header. The method itself actually checks if the header exists, but we just negate that call. So that part of the logic looks like this.

($this->ajax() && ! $this->pjax())

The next part is to check "or do we want json". That is accomplished by getting the acceptable content types. Like in the following example.

public function wantsJson()
{
    $acceptable = $this->getAcceptableContentTypes();

    return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
}

Acceptable content types are just an array of the strings you provide through the Accept header. If you do not provide an Accept header, you will be defaulted to */*. So you will notice above that it will check the first acceptable header and see if it contains /json or +json. This is a pretty standard thing to do, so basically its looking for one of these values, application/json or application/vnd.api+json.

Since you are not providing an Accept header, the expectsJson() check will fail and you are redirected to login as a guest. Hope this helps you!

All 3 comments

Hey @duccanh0022,

It is working properly if you take a deep dive into the method. What expectsJson() does is first check if the request is AJAX and !PJAX. It checks whether the request is AJAX by the existence of the X-Requested-With header and by checking if it's value is XMLHttpRequest. If that is true, that first part will pass. The second part, is !PJAX, that is done by checking for the X-PJAX header. The method itself actually checks if the header exists, but we just negate that call. So that part of the logic looks like this.

($this->ajax() && ! $this->pjax())

The next part is to check "or do we want json". That is accomplished by getting the acceptable content types. Like in the following example.

public function wantsJson()
{
    $acceptable = $this->getAcceptableContentTypes();

    return isset($acceptable[0]) && Str::contains($acceptable[0], ['/json', '+json']);
}

Acceptable content types are just an array of the strings you provide through the Accept header. If you do not provide an Accept header, you will be defaulted to */*. So you will notice above that it will check the first acceptable header and see if it contains /json or +json. This is a pretty standard thing to do, so basically its looking for one of these values, application/json or application/vnd.api+json.

Since you are not providing an Accept header, the expectsJson() check will fail and you are redirected to login as a guest. Hope this helps you!

oh, very clearly,
Thank you so much!

In Passport 5.0.3, a bug was fixed which prevented the correct error response on JSON calls with incorrect authentication. This now works as intended.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Adesubomi picture Adesubomi  路  4Comments

s4uron picture s4uron  路  3Comments

aluferraz picture aluferraz  路  3Comments

ghost picture ghost  路  3Comments

Patskimoto picture Patskimoto  路  3Comments