File manager - Edit - /var/www/html/portalHomolog/app/Http/Controllers/Accounts/GovBrController.php
Back
<?php namespace App\Http\Controllers\Accounts; use App\Http\Controllers\Controller; use App\Http\Resources\Accounts\GovBrResource; use App\Http\Services\Accounts\GovBrService; use Illuminate\Http\Request; use Jumbojett\OpenIDConnectClient; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use Illuminate\Support\Str; use Illuminate\Support\Facades\Http; use Illuminate\Http\RedirectResponse; class GovBrController extends Controller { private GovBrService $service; public function __construct() { $this->service = new GovBrService(); } protected function buildClient(): OpenIDConnectClient { $client = new OpenIDConnectClient( config('services.govbr.base_url'), config('services.govbr.client_id'), config('services.govbr.client_secret') ); $client->setRedirectURL(config('services.govbr.redirect')); $client->addScope(['openid', 'profile', 'email']); // força TLS $client->setVerifyPeer(true); $client->setVerifyHost(true); return $client; } public function redirectToProvider(): RedirectResponse { try { // Valida se as configurações estão presentes $baseUrl = config('services.govbr.base_url'); $clientId = config('services.govbr.client_id'); $redirectUri = config('services.govbr.redirect'); if (empty($baseUrl) || empty($clientId) || empty($redirectUri)) { Log::error('Configurações do GOV.BR incompletas', [ 'base_url' => !empty($baseUrl), 'client_id' => !empty($clientId), 'redirect' => !empty($redirectUri), ]); return redirect()->route('admin.login') ->with('error', 'Configuração do GOV.BR incompleta. Entre em contato com o administrador.'); } $client = $this->buildClient(); // Tenta obter a URL de autorização manualmente se authenticate() falhar try { $response = $client->authenticate(); // Se authenticate() retornar um RedirectResponse, usa ele if ($response instanceof RedirectResponse) { return $response; } // Se authenticate() retornar uma string (URL), redireciona para ela if (is_string($response) && filter_var($response, FILTER_VALIDATE_URL)) { return redirect()->away($response); } } catch (\Throwable $authError) { Log::warning('authenticate() falhou, tentando método alternativo: ' . $authError->getMessage()); // Tenta construir a URL de autorização manualmente $authUrl = $baseUrl . '/authorize?' . http_build_query([ 'client_id' => $clientId, 'redirect_uri' => $redirectUri, 'response_type' => 'code', 'scope' => 'openid profile email', 'state' => Str::random(40), ]); return redirect()->away($authUrl); } // Se chegou aqui, algo deu errado Log::error('GOV.BR authenticate() retornou valor inesperado', [ 'type' => gettype($response), 'value' => $response, ]); return redirect()->route('admin.login') ->with('error', 'Erro ao iniciar autenticação com GOV.BR. Tente novamente.'); } catch (\Throwable $e) { Log::error('Erro ao redirecionar para GOV.BR: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), 'config' => [ 'base_url' => config('services.govbr.base_url'), 'client_id' => config('services.govbr.client_id'), 'redirect' => config('services.govbr.redirect'), ] ]); return redirect()->route('admin.login') ->with('error', 'Erro ao iniciar autenticação com GOV.BR: ' . $e->getMessage()); } } public function handleProviderCallback(): RedirectResponse { try { Log::info('GOV.BR Callback iniciado', ['request' => request()->all()]); $client = $this->buildClient(); Log::info('GOV.BR Client criado'); $client->authenticate(); Log::info('GOV.BR authenticate() executado'); $claims = $client->getVerifiedClaims(); Log::info('GOV.BR Claims obtidos', ['has_claims' => !empty($claims)]); if (!$claims) { Log::error('GOV.BR: Claims vazios'); return redirect()->route('admin.login') ->with('error', 'Não foi possível obter as informações da conta gov.br.'); } $sub = $claims->sub ?? null; $email = mb_strtolower($claims->email ?? null); $name = $claims->name ?? null; $birthdate = $claims->birthdate ?? null; Log::info('GOV.BR Dados extraídos', [ 'sub' => $sub, 'email' => $email, 'name' => $name, 'has_cpf' => !empty($claims->cpf), 'preferred_username' => $claims->preferred_username ?? null, ]); $cpf = null; if (!empty($claims->cpf)) { $cpf = preg_replace('/\D/', '', $claims->cpf); } if (!$cpf && !empty($claims->preferred_username) && preg_match('/^\d{11}$/', $claims->preferred_username)) { $cpf = $claims->preferred_username; } if (!$cpf) { Log::error('GOV.BR: CPF não encontrado', ['claims_keys' => array_keys((array)$claims)]); return redirect()->route('admin.login') ->with('error', 'Não foi possível obter o CPF da conta gov.br.'); } Log::info('GOV.BR CPF encontrado', ['cpf' => $cpf]); $user = $this->service->getUserWithCPF($cpf); Log::info('GOV.BR Usuário buscado', ['user_exists' => !empty($user), 'user_id' => $user->id ?? null]); $fullName = $this->resolveFullname($name ?? ''); Log::info('GOV.BR Nome resolvido', ['fullName' => $fullName]); if (!$user) { Log::info('GOV.BR: Criando novo usuário'); $profilePhoto = GovBrResource::resolveProfilePhoto($claims->picture ?? null); $array_user = [ 'structure_id' => null, 'firstName' => $fullName['firstName'], 'lastName' => $fullName['lastName'], 'cpf' => $cpf, 'email' => $email, 'password' => bcrypt(Str::random(40)), 'status' => 'ATIVADO', 'isPasswordDefault' => 0, 'photo' => $profilePhoto, 'govbr_sub' => $sub, 'govbr_access_token' => $client->getAccessToken(), 'govbr_refresh_token' => $client->getRefreshToken(), 'govbr_id_token' => $client->getIdToken(), 'govbr_email' => $email, ]; $array_pessoa = [ 'user_id' => null, 'nomeCompleto' => $name ?? ($fullName['firstName'] . ' ' . $fullName['lastName']), 'dtaNascimento' => $birthdate ?? null, ]; $result = $this->service->create($array_user, $array_pessoa); Log::info('GOV.BR: Usuário criado, redirecionando'); return $result; } else { Log::info('GOV.BR: Atualizando usuário existente', ['user_id' => $user->id]); $array_user = [ 'firstName' => $fullName['firstName'], 'lastName' => $fullName['lastName'], 'govbr_sub' => (!$user->govbr_sub && $sub) ? $sub : null, 'govbr_access_token' => $client->getAccessToken(), 'govbr_refresh_token' => $client->getRefreshToken(), 'govbr_id_token' => $client->getIdToken(), 'govbr_email' => $email, ]; if (empty($user->photo)) { $array_user['photo'] = GovBrResource::resolveProfilePhoto($claims->picture ?? null); } $array_pessoa = [ 'user_id' => $user->id, 'nomeCompleto' => $name ?? ($fullName['firstName'] . ' ' . $fullName['lastName']), 'dtaNascimento' => $birthdate ?? null, ]; $result = $this->service->update($user, $array_user, $array_pessoa); Log::info('GOV.BR: Usuário atualizado, redirecionando'); return $result; } } catch (\Throwable $e) { Log::error('Erro no callback do GOV.BR: ' . $e->getMessage(), [ 'exception' => $e, 'trace' => $e->getTraceAsString(), 'file' => $e->getFile(), 'line' => $e->getLine(), ]); return redirect()->route('admin.login') ->with('error', 'Erro ao autenticar com GOV.BR: ' . $e->getMessage()); } } /** * Resolve o endpoint de logout do provedor Gov.br sem usar métodos protegidos da lib. */ private function resolveLogoutEndpoint(): ?string { $configured = config('services.govbr.end_session_endpoint'); if (!empty($configured)) { return $configured; } $baseUrl = rtrim((string) config('services.govbr.base_url'), '/'); if (empty($baseUrl)) { return null; } try { $response = Http::timeout(5)->get($baseUrl . '/.well-known/openid-configuration'); if ($response->successful()) { $data = $response->json(); if (!empty($data['end_session_endpoint'])) { return $data['end_session_endpoint']; } } } catch (\Throwable $e) { // silencioso: usaremos fallback local } return $baseUrl . '/logout'; } public function logout(Request $request): RedirectResponse { $user = Auth::user(); Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); $postLogout = config('services.govbr.post_logout_redirect'); $clientId = config('services.govbr.client_id'); try { $logoutEndpoint = $this->resolveLogoutEndpoint(); if ($logoutEndpoint) { $params = [ 'client_id' => $clientId, 'post_logout_redirect_uri' => $postLogout, ]; if ($user && $user->govbr_id_token) { $params['id_token_hint'] = $user->govbr_id_token; } // limpa tokens locais $user->update([ 'govbr_sub' => null, 'govbr_access_token' => null, 'govbr_refresh_token' => null, 'govbr_id_token' => null, ]); return redirect()->away($logoutEndpoint . '?' . http_build_query($params)); } } catch (\Throwable $e) { return redirect()->route('admin.login') ->with('error', 'Erro ao tentar desconectar da conta GOV.BR: ' . $e->getMessage()); } return redirect($postLogout); } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings