I’m trying to implement a custom OAuth2 grant type in Laravel Passport for mobile authentication, but I’m encountering the following error
{
"error": "unsupported_grant_type",
"error_description": "The authorization grant type is not supported by the authorization server."
}
Here is the custom MobileGrant class I’m using:
namespace App\Grants;
use App\Enums\UserType;
use Laravel\Passport\Bridge\UserRepository;
use Laravel\Passport\Bridge\RefreshTokenRepository;
use Laravel\Passport\Bridge\AccessToken;
use League\OAuth2\Server\Grant\AbstractGrant;
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
use Psr\Http\Message\ServerRequestInterface;
use DateInterval;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
class MobileGrant extends AbstractGrant
{
public function __construct(UserRepository $userRepository, RefreshTokenRepository $refreshTokenRepository)
{
$this->setUserRepository($userRepository);
$this->setRefreshTokenRepository($refreshTokenRepository);
}
public function respondToAccessTokenRequest(
ServerRequestInterface $request,
ResponseTypeInterface $responseType,
DateInterval $accessTokenTTL
) {
$mobile = $this->getRequestParameter('mobile', $request);
$confirmCode = $this->getRequestParameter('mobile_confirm_code', $request);
if (!$mobile || !$confirmCode) {
return response()->json(['message' => 'Mobile number and confirmation code are required.'], 400);
}
$user = User::where('mobile', $mobile)->first();
if (User::where(['mobile' => $mobile, 'mobile_confirm_code' => $confirmCode])->exists() || $confirmCode == "1234") {
if (!self::isExpiredConfirmCode($user)) {
if (User::where(['mobile' => $mobile])->whereNull('mobile_verified_at')->exists()) {
User::where('mobile', $mobile)->update([
'mobile_verified_at' => Carbon::now()->format('Y-m-d H:i:s')
]);
}
Auth::login($user);
$role = UserType::hasValue($user->role) ? $user->role : null;
$accessToken = $this->issueAccessToken($accessTokenTTL, $user->id, $role);
$refreshToken = $this->issueRefreshToken($accessToken);
return [
'token_type' => 'Bearer',
'expires_in' => $accessTokenTTL->s,
'access_token' => (string) $accessToken,
'refresh_token' => (string) $refreshToken,
];
} else {
return response()->json(['message' => 'Confirmation code expired.'], 400);
}
} else {
return response()->json(['message' => 'Invalid confirmation code.'], 400);
}
}
public function getIdentifier()
{
return 'mobile';
}
public function isExpiredConfirmCode($user)
{
return Carbon::parse($user->expire_mobile_confirm_code)->lt(Carbon::now());
}
}
In my AppServiceProvider, I enable the custom grant type:
public function boot(): void
{
app(AuthorizationServer::class)->enableGrantType(
new MobileGrant(
app()->make(\Laravel\Passport\Bridge\UserRepository::class),
app()->make(\Laravel\Passport\Bridge\RefreshTokenRepository::class)
),
new \DateInterval('P1Y') // Access token expiration time
);
}
However, when I try to request the token with the following data:
{
"grant_type": "mobile",
"client_id": "client-id-here",
"client_secret": "client-secret-here",
"mobile": "mobileNumber",
"mobile_confirm_code": "1234",
"scope": ""
}
I get the unsupported_grant_type error.
Could anyone help me figure out why this error occurs and how to resolve it? I have enabled the custom grant type in AppServiceProvider, but it’s still not working.
Thanks in advance!
Getting ‘unsupported_grant_type’ error when implementing a custom OAuth2 grant in Laravel Passport