Cómo restringir el login con Google a un dominio institucional en Laravel

Cuando una organización quiere que solo su gente entre a una aplicación (por ejemplo, el correo @universidad.edu.co), la tentación es confiar en el selector de cuentas de Google. Es un error común: restringir el dominio en el botón no protege la aplicación. Este artículo muestra cómo hacerlo bien con Laravel Socialite.

1. El parámetro hd es solo una pista

Google acepta el parámetro hd (hosted domain) para que el selector de cuentas muestre primero las cuentas de ese dominio. Pero quien arma la URL de autorización a mano puede quitarlo o cambiarlo, así que no es una barrera de seguridad.

return Socialite::driver('google')
    ->with(['hd' => 'universidad.edu.co'])
    ->redirect();

Úsalo por comodidad de usuario, nunca como control de acceso.

2. Valida el dominio en el callback

La comprobación que importa ocurre en el servidor, con los datos que devuelve Google:

$googleUser = Socialite::driver('google')->user();

$email = strtolower($googleUser->getEmail());
$allowedDomain = 'universidad.edu.co';

abort_unless(str_ends_with($email, '@'.$allowedDomain), 403);

Dos detalles que evitan fallos sutiles:

  • Compara contra '@'.$dominio, no solo contra el dominio. Con str_ends_with($email, 'universidad.edu.co') también pasaría alguien@falsouniversidad.edu.co.
  • Normaliza a minúsculas antes de comparar.

3. Comprueba que el correo esté verificado

La respuesta de Google incluye si el correo fue verificado. Exígelo antes de crear o asociar la cuenta:

abort_unless(($googleUser->user['email_verified'] ?? false) === true, 403);

4. Crea o actualiza el usuario y asigna el rol

Una vez validado, busca al usuario por correo y asígnale un rol por defecto con el mínimo de privilegios. Los permisos elevados se conceden después de forma explícita, no se deducen del correo.

$user = User::firstOrCreate(
    ['email' => $email],
    ['name' => $googleUser->getName(), 'password' => Str::random(40)],
);

Auth::login($user);

5. Pruébalo

Escribe al menos tres pruebas: un correo del dominio permitido entra, un correo de otro dominio recibe 403 y un correo con dominio parecido (falsouniversidad.edu.co) también recibe 403. Son las que protegen de regresiones cuando alguien refactorice el callback.

Resumen

Capa Para qué sirve ¿Es seguridad?
Parámetro hd Mejorar la experiencia del selector No
Validación del dominio en el servidor Control de acceso real Sí
email_verified Evitar correos no confirmados Sí
Rol por defecto sin privilegios Limitar el daño Sí