Запрошенный код авторизации типа Grant с помощью Curl и WebPhp

Кемеровские программисты php общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Запрошенный код авторизации типа Grant с помощью Curl и Web

Сообщение Anonymous »

Я внедрил, и он работает правильно в моем проекте, пароль типа Grant для входа в систему с использованием адреса электронной почты и пароля
Теперь я активировал код авторизации типа Grant для входа/регистрации в Google используя библиотеку https://github.com/thephpleague/oauth2-google
Я тестирую с помощью Curl, и он выдает эту ошибку
Monolog

Код: Выделить всё

[2024-11-13T11:04:48.647981+00:00] AuthService.INFO: Getting client_entity for token request {"client_id":"cdc-client","client_secret":"d9e640ab946ef196003f5972913c570d918bef8e480daa206a10227b87b02cd0"} []
[2024-11-13T11:04:48.658902+00:00] AuthService.INFO: Scopes obtained for user {"user_id":"120","scopes":["view_profile","edit_profile"]} []
[2024-11-13T11:04:48.659074+00:00] AuthService.INFO: Data prepared for token request {"request_data":{"grant_type":"authorization_code","client_id":"cdc-client","client_secret":"d9e640ab946ef196003f5972913c570d918bef8e480daa206a10227b87b02cd0","redirect_uri":"http://localhost:9000/auth/google/callback","code":"4/0AeanS0bLaotKwmbe7AScGHrlnY5zbfSg6QWOFxB4LpOctZ348OgefbxOEuHcZIxiQ2n7RQ","scope":"view_profile edit_profile"},"auth_server_url":"http://localhost:9000/oauth/token"} []
[2024-11-13T11:04:48.838709+00:00] AuthService.ERROR: Error obtaining access token {"exception_message":"Server error: `POST http://localhost:9000/oauth/token` resulted in a `500 Internal Server Error` response:\nThe request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, o (truncated...)\n","request_data":{"grant_type":"authorization_code","client_id":"cdc-client","client_secret":"d9e640ab946ef196003f5972913c570d918bef8e480daa206a10227b87b02cd0","redirect_uri":"http://localhost:9000/auth/google/callback","code":"4/0AeanS0bLaotKwmbe7AScGHrlnY5zbfSg6QWOFxB4LpOctZ348OgefbxOEuHcZIxiQ2n7RQ","scope":"view_profile edit_profile"},"response_body":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed."} []

[2024-11-13T11:04:39.389224+00:00] GoogleProviderController.INFO: Redirecting to Google with auth URL {"url":"https://accounts.google.com/o/oauth2/v2/auth?scope=openid%20email%20profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=3b70e4b1b3afe8daa53ed28ce758d661&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A9000%2Fauth%2Fgoogle%2Fcallback&client_id=1092814058687-f20kojo6falrbgam840cliiif2bpb2ao.apps.googleusercontent.com"} []
[2024-11-13T11:04:47.343896+00:00] GoogleProviderController.INFO: Starting Google callback processing {"params":{"state":"3b70e4b1b3afe8daa53ed28ce758d661","code":"4/0AeanS0bLaotKwmbe7AScGHrlnY5zbfSg6QWOFxB4LpOctZ348OgefbxOEuHcZIxiQ2n7RQ","scope":"email profile openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email","authuser":"0","prompt":"consent"}} []
[2024-11-13T11:04:47.344119+00:00] GoogleProviderController.INFO: Obtaining access token from Google {"authorization_code":"4/0AeanS0bLaotKwmbe7AScGHrlnY5zbfSg6QWOFxB4LpOctZ348OgefbxOEuHcZIxiQ2n7RQ"} []
[2024-11-13T11:04:47.952762+00:00] GoogleProviderController.INFO:  Validating id_token {"id_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFkYzBmMTcyZThkNmVmMzgyZDZkM2EyMzFmNmMxOTdkZDY4Y2U1ZWYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIxMDkyODE0MDU4Njg3LWYyMGtvam82ZmFscmJnYW04NDBjbGlpaWYyYnBiMmFvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiMTA5MjgxNDA1ODY4Ny1mMjBrb2pvNmZhbHJiZ2FtODQwY2xpaWlmMmJwYjJhby5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwOTI5NDkwOTM4MDExMDA0NjQ2NCIsImVtYWlsIjoiY2VudHJhbGRvY2F2YWNvLnN1cG9ydGVAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF0X2hhc2giOiJiM28wMGRYc1NaUGo3NXAxWXEzcFdnIiwibmFtZSI6IkNlbnRyYWwgZG8gQ2F2YWNvIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FDZzhvY0luMXJHcWxkQWc4OU5mRzdsbEU1LUEtYmdGMVlSaUkyNFRaMDlrX1dXMnhtVzBUZz1zOTYtYyIsImdpdmVuX25hbWUiOiJDZW50cmFsIGRvIENhdmFjbyIsImlhdCI6MTczMTQ5NTg4NywiZXhwIjoxNzMxNDk5NDg3fQ.NIqTtyBzXJrJJPXirCJVUi-Tthu6XE3S31A7mQ6b3wTUIaND3mNJJZ-HLsqbNS6VWoh-sPtIZ67fkBhnV7AcLIvxpNrbNHSTiVCsnzg8FCi9Z2lJW4jAv8VNlAhDkHKutlihCt_v-MQlK63fctvutsj-rZ8M-HpFfm3rasDAC1L1jFEGdbiZ4LVAYDy_wsuPAdhK3slGdZs8KIH2qyn-zzWKjyZl4GYeCYw6_3Z_dq8BCo9wDomuYcVC7IL_YXCtyeMX6bFVHBF9ZkeVCeTUDyzBVN4ZkQ2siEWBpEArhWI5tfykPdwZKHYTxplGeEkWgUr9KuOs_cAMmSna6m12kw"} []
[2024-11-13T11:04:47.953145+00:00] GoogleProviderController.INFO: Starting id_token validation with Google {"id_token":"eyJhbGciOiJSUzI1NiIsImtpZCI6IjFkYzBmMTcyZThkNmVmMzgyZDZkM2EyMzFmNmMxOTdkZDY4Y2U1ZWYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIxMDkyODE0MDU4Njg3LWYyMGtvam82ZmFscmJnYW04NDBjbGlpaWYyYnBiMmFvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiMTA5MjgxNDA1ODY4Ny1mMjBrb2pvNmZhbHJiZ2FtODQwY2xpaWlmMmJwYjJhby5hcHBzLmdvb

Скручивание

Код: Выделить всё

curl -X POST http://localhost:9000/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=cdc-client" \
-d "client_secret=d9e640ab946ef196003f5972913c570d918bef8e480daa206a10227b87b02cd0" \
-d "redirect_uri=http://localhost:9000/auth/google/callback" \
-d "code=4/0AVG7fiT52c1QiaVVJjWdPb7A-izfVsZ4cRfJEaTr8MzY_9AKJXY40XU6A204xOMy2gESvg"

The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.%             ➜  ~
Метод класса AuthService для генерации локального токена

Код: Выделить всё

public function obtainAccessTokenByAuthCode(UserEntity $userEntity, string $authCode, Request $request, Response $response): Response
{
// Obtenha o client_id e secret do cliente local
$clientEntity = $this->clientRepository->getFirstClientEntity();
$this->logger->info("Obtendo client_entity para requisição de token", [
'client_id' => $clientEntity->getIdentifier(),
'client_secret' => $clientEntity->getSecret()
]);

// Obtenha os escopos finalizados do ScopeRepository
$scopes = $this->scopeRepository->getScopesByUserId($userEntity->getIdentifier());
$scopeIdentifiers = array_map(fn($scope) => $scope->getIdentifier(), $scopes);
$this->logger->info("Escopos obtidos para o usuário", [
'user_id' => $userEntity->getIdentifier(),
'scopes' => $scopeIdentifiers
]);

// Dados para requisição de token
$requestData = [
'grant_type' => 'authorization_code',
'client_id' => $clientEntity->getIdentifier(),
'client_secret' => $clientEntity->getSecret(),
'redirect_uri' => $_ENV['GOOGLE_REDIRECT_URI'],
'code' => $authCode,
'scope' => implode(' ', $scopeIdentifiers)
];

$this->logger->info("Dados preparados para solicitação de token", [
'request_data' => $requestData,
'auth_server_url' => $this->authServerUrl . '/oauth/token'
]);

try {
$authResponse = $this->httpClient->post($this->authServerUrl .  '/oauth/token', [
'form_params' => $requestData
]);

// Obtenha o corpo completo da resposta para logs
$responseBody = (string) $authResponse->getBody();
$this->logger->info("Resposta completa do servidor de autenticação recebida", [
'status_code' => $authResponse->getStatusCode(),
'response_body' => json_decode($responseBody, true)
]);

return $response->withHeader('Content-Type', 'application/json')
->withStatus($authResponse->getStatusCode())
->withBody($authResponse->getBody());

} catch (\Exception $e) {
$responseBody = method_exists($e, 'getResponse') ? (string) $e->getResponse()->getBody() : 'No response body';
$this->logger->error("Erro ao obter token de acesso detalhado", [
'exception_message' => $e->getMessage(),
'request_data' => $requestData,
'response_body' => $responseBody
]);

return $this->jsonResponse($response, [
'error' => 'token_request_failed',
'message' => $e->getMessage(),
'response_body' => $responseBody
], 500);
}

}
Метод класса GoogleProviderController

Код: Выделить всё

public function handleGoogleCallback(Request $request, Response $response): Response
{
$params = $request->getQueryParams();

// Verificar estado para prevenir CSRF
if (empty($params['state']) || ($params['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
$this->logger->error('Estado inválido na autenticação com o Google', ['state_received' => $params['state'], 'session_state' => $_SESSION['oauth2state']]);
return $response->withStatus(400)->write('Estado inválido');
}

try {
$this->logger->info('Iniciando processamento do callback do Google', ['params' => $params]);

// 1. Obter o token de acesso do Google usando o código de autorização
$this->logger->info('Obtendo token de acesso do Google', ['authorization_code' => $params['code']]);
$accessToken = $this->googleProvider->getAccessToken('authorization_code', ['code' => $params['code']]);

$idToken = $accessToken->getValues()['id_token'] ?? null;
if (!$idToken) {
$this->logger->error('id_token não encontrado na resposta do Google', ['accessToken' => $accessToken]);
throw new \Exception("id_token não encontrado.");
}

// 2. Validar e extrair o id_token
$this->logger->info('Validando id_token', ['id_token' => $idToken]);
$tokenInfo = $this->validateIdToken($idToken);
if (empty($tokenInfo['email'])) {
$this->logger->error('E-mail ausente nos dados do Google.', ['tokenInfo' => $tokenInfo]);
throw new \Exception("E-mail ausente nos dados retornados pelo Google.");
}

// 3.  Criar ou buscar usuário local
$googleUserData = [
'sub' => $tokenInfo['sub'],
'email' => $tokenInfo['email'],
'name' => $tokenInfo['name'],
'picture' => $tokenInfo['picture'],
'email_verified' => $tokenInfo['email_verified']
];

$this->logger->info('Dados do usuário recebidos do Google', ['googleUserData' => $googleUserData]);

// Buscar ou criar usuário
$this->logger->info('Buscando ou criando usuário local', ['googleUserData' => $googleUserData]);
$userEntity = $this->findOrCreateUser($googleUserData);

// Gerar token de acesso local
$this->logger->info('Gerando token de acesso local', ['user_id' => $userEntity->getUserId(), 'code' => $params['code']]);
$localAccessTokenResponse = $this->authService->obtainAccessTokenByAuthCode($userEntity, $params['code'], $request, $response);

// Decodificar a resposta para verificar o token gerado
$tokenData = json_decode((string) $localAccessTokenResponse->getBody(), true);
if (!isset($tokenData['access_token'])) {
$this->logger->error("Falha ao gerar token de acesso local após o login com o Google", ['localAccessTokenResponse' => $localAccessTokenResponse]);
$response->getBody()->write('Erro interno de autenticação');
return $response->withStatus(500);
}

$this->logger->info('Token de acesso local gerado com sucesso', ['tokenData' => $tokenData]);

// Configurar o cookie com o token de acesso
setcookie('access_token', $tokenData['access_token'], [
'expires' => time() + 3600,
'path' => '/',
'secure' => false,
'httponly' => true,
'samesite' => 'Strict'
]);

// Redirecionar de acordo com o papel do usuário
$username = $userEntity->getUsername();
$redirectUrl = match ($userEntity->getRole()) {
'admin' => '/admin/',
'moderator' => '/moderator/',
'user' => '/u/@' . $username,
'developer' => '/developer/',
default => '/u/@' . $username,
};

$this->logger->info('Usuário autenticado com sucesso e redirecionado', [
'user_id' => $userEntity->getUserId(),
'redirect_url' => $redirectUrl
]);

return $response->withHeader('Location', $redirectUrl)->withStatus(302);

} catch (\Exception $e) {
$this->logger->error('Erro ao processar callback do Google: ' . $e->getMessage(), ['exception' => $e]);
return $response->getBody()->write('Erro durante a autenticação com o Google.');
return $response->withStatus(500);
}
}
Маршруты

Код: Выделить всё

$app->get('/auth/google', GoogleProviderController::class . ':redirectToGoogle');
$app->get('/auth/google/callback', GoogleProviderController::class . ':handleGoogleCallback');

$app->post('/oauth/token', function (Request $request, Response $response) use ($server) {
try {
return $server->respondToAccessTokenRequest($request, $response);
} catch (OAuthServerException $exception) {
return $exception->generateHttpResponse($response);
} catch (\Exception $exception) {
// Correção para criação do Stream com recurso
$body = new Stream(fopen('php://temp', 'r+'));
$body->write($exception->getMessage());
return $response->withStatus(500)->withBody($body);
}
});
Моя проблема в основном в следующем, я получаю информацию от Google и она действительна, однако при переключении на локальный токен она не генерируется

Подробнее здесь: https://stackoverflow.com/questions/791 ... rl-and-web
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение