实现自定义 OAuth2 授权时出现“unsupported_grant_type”错误

问题描述 投票:0回答:1

我正在尝试在 Laravel Passport 中实现自定义 OAuth2 授权类型以进行移动身份验证,但遇到以下错误

{
    "error": "unsupported_grant_type",
    "error_description": "The authorization grant type is not supported by the authorization server."
}

这是我正在使用的自定义 MobileGrant 类:

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());
    }
}

在我的 AppServiceProvider 中,我启用自定义授予类型:

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
    );
}

但是,当我尝试使用以下数据请求令牌时:

{
    "grant_type": "mobile",
    "client_id": "client-id-here",
    "client_secret": "client-secret-here",
    "mobile": "mobileNumber",
    "mobile_confirm_code": "1234",
    "scope": ""
}

我收到 unsupported_grant_type 错误。

任何人都可以帮我找出为什么会出现此错误以及如何解决它吗?我已经在 AppServiceProvider 中启用了自定义授权类型,但它仍然不起作用。

提前致谢!

在 Laravel Passport 中实现自定义 OAuth2 授权时出现“unsupported_grant_type”错误。

我进行了各种调试尝试,但无法得出结论。我在 mobileGrant 中记录了请求数据,并且数据传输正确。 我也确信客户端 ID 和客户端机密信息是正确的。

 public function respondToAccessTokenRequest(
    ServerRequestInterface $request,
    ResponseTypeInterface $responseType,
    DateInterval $accessTokenTTL
 ) {
    dd($request);
 }

在一些文档中,提到还应该添加passport::routes(),但最新的Passport文档表明没有必要。

php laravel laravel-passport laravel-11
1个回答
0
投票

如果您的自定义授权类型注册是在 Passport 启动后进行的,则可能不会生效。

您可以尝试将资助注册逻辑移至

AuthServiceProvider
而不是
AppServiceProvider

您还应该尝试刷新缓存和配置。

php artisan cache:clear
php artisan config:clear
php artisan config:cache
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.