Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Danaq's avatar
Level 1

passport in laravel 5.5 - grant_type not supported

Hi there,

like my last question here I hope you can help me again.

Im using Laravel 5.5 with passport 4.0

I already followed the documentation: https://laravel.com/docs/5.5/passport#password-grant-tokens

But I will only use the method to grant tokens by credetials.

Because the connection is used by a smartphone I setted the configuration in the

//AuthServiceProvider

public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
        
    Passport::enableImplicitGrant();

        Passport::tokensExpireIn(Carbon::now()->addDays(config('APP_ACCESS_TOKEN_EXPIRE_IN')));

        Passport::refreshTokensExpireIn(Carbon::now()->addDays(config('APP_REFRESH_TOKEN_EXPIRE_IN')));
    }

like this. I added the 'enableimplicitGrant' cause the documentation called that as best practice for conecitons to mobile-devices.

I used the artisan commands

php artisan passport:client --password
php artisan passport:keys

The rest of my configuration looks like this:

//config/database.php

'mysql' => [
            [...]
            'prefix' => '',
            'strict' => true,
            'engine' => 'InnoDB', //changes from 'null'
        ],

//config/auth.php

'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport', //changed from 'token'
            'provider' => 'users',
        ],
    ],

//config/app.php

    /*
         * Package Service Providers...
         */
        Laravel\Passport\PassportServiceProvider::class, //added 

And the User-Model was extended:

//User.php

[...]
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens,Notifiable;
[...]

So the login-Request as well as the register-request enters the particular controller

//loginController.php

class LoginController extends Controller
{
    use IssueTokenTrait;

    private $client;

    public function __construct() 
    {   
        $this->middleware('guest')->except('logout');
        $this->client = Client::find(1); //there is only one client present in the database
    }

    public function login(ApiRequest\AppLoginRequest $request) {
        return $this->issueToken($request, 'password');
    }

    public function refresh(ApiRequest\AppLoginRequest $request) {
        $this->validate($request, [
            'refresh_token' => 'required'
        ]);

        return $this->issueToken($request, 'refresh_token');
    }

    public function logout(Request $request) {
        $accessToken = Auth::user()->token();

        DB::table('oauth_refresh_tokens')
            ->where('access_token_id', $accessToken->id)
            ->update(['revoked' => true]);

        $accessToken->revoke();

        return response()->json([], 204);
    }
}

The used IssueTokenTrait - The params-array should be built according to the documentation.

//IssueTokenTrait.php

    public function issueToken(Request $request, $grant_type, $scope = '*') {
        $params = [
            'grant_type' => $grant_type,
            'client_id' => $this->client->id,
            'client_secret' => $this->client->secret,
            'username' => $request->username ?: $request->email,
        'password' => $request->password, 
        'scope' => $scope,
        ];
        

        $request->request->add($params);
        $proxy = Request::create('oauth/token', 'POST');

        return Route::dispatch($proxy);
    }

But every time I only get the response:

{
    "error": "unsupported_grant_type",
    "message": "The authorization grant type is not supported by the authorization server.",
    "hint": "Check the `grant_type` parameter"
}

I already rummaged in the venfor/laravel/passport folder and the vendor/league/oauth2-server/ folder to find where the error-message is thrown. I found it but it doesn't help me.

Is there someone who can help me with that?

UPDATE

When I call the route oauth/token directly with this body:

username: [email protected]
password: myPassword
grant_type: password
client_id: 1
client_secret: 5SMtQmPo2wKyt6OxWZvRQIhG2lw4n2zxMRxW1nMo
scope: *

Then the reply is correct.

So this is probably the problem?

//loginController

$request->request->add($params);        
$proxy = Request::create('oauth/token', 'POST');
return Route::dispatch($proxy);

How can I fix this? Is there an adaption necessary to be laravel 5.5 conform?

UPDATE-2

Even the request i want to forward has the correct header in my opinion:

+headers: HeaderBag {#48
          #headers: array:12 [
            "host" => array:1 [
              0 => "192.168.56.101:8080"
            ]
            "connection" => array:1 [
              0 => "keep-alive"
            ]
            "content-length" => array:1 [
              0 => "88"
            ]
            "accept" => array:1 [
              0 => "application/json"
            ]
            "cache-control" => array:1 [
              0 => "no-cache"
            ]
            "origin" => array:1 [
              0 => "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop"
            ]
            "user-agent" => array:1 [
              0 => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
            ]
            "postman-token" => array:1 [
              0 => "9e01eae8-4252-f530-7fff-370ffdcaac1d"
            ]
            "dnt" => array:1 [
              0 => "1"
            ]
            "accept-encoding" => array:1 [
              0 => "gzip, deflate"
            ]
            "accept-language" => array:1 [
              0 => "en,de-DE;q=0.9,de;q=0.8,en-US;q=0.7"
            ]
          ]

Is the Content-Type missing in the request-header?

CONCLUSION, TLDR

$params = [
            'grant_type' => $grant_type, //is called as 'password'
            'client_id' => $this->client->id, //only one password client present, ID = 1
            'client_secret' => $this->client->secret, //client secret from database
            'username' => $request->username ?: $request->email, //login or register, so credentials will be sent
        'password' => $request->password, 
        'scope' => $scope, //is setted to '*' per default
        ];
  • I don't want to deliver the ID and the SECRET to the mobile devices for connecting so I extend the request with
$request->request->add($params);
$proxy = Request::create('oauth/token', 'POST');

return Route::dispatch($proxy);
  • when calling the dispatch-address directly the process works
  • the content-type-header seems not be the problem, the error occurs in both cases
  • changing the redirect-url of the client in the database helps not, redirecting to 'http://localhost' as defined should not working because the laravel is served as 192.168.56.101:8080

UPDATE-3 - PROBLEM ISOLATED

The problem is to use custom requests when entering the login-method. The request ist then used in the IssueToken-method but there a new request is built and dispatched to a new route.

I cannot figure out how but the endpoint of the oauth/token-route get a request object of an interface not used befor but has still access to the data from the first request as long as this is a type hinted Illuminate\Http\Request-object.

Check out this thread may we will find the solution there: https://laracasts.com/discuss/channels/laravel/laravel-passport-using-custom-request

0 likes
2 replies
joshuauyi's avatar

Just replying in case you didn't find a solution. I also experienced this issue in Laravel 9.

The service container always seems to resolve the original request even after the new one is dispatched, so the issue token controller in passport would still get those params, hence it wouldn't have the required params to issue a token.

The solution is simply to swap Route::dispatch($proxy); with App::handle($proxy);

joshuauyi's avatar

Just following up here to say that, I discovered a new issue where other parts of Laravel forget the original request after doing this, to handle this, modify App::handle to this

$originalRequest = request();
App::handle($proxy);
App::instance('request', $originalRequest);

Please or to participate in this conversation.