google api - tienes - Restringir el correo electrónico de inicio de sesión con Google OAuth2.0 a un nombre de dominio específico
oauth login google (4)
Parece que no puedo encontrar ninguna documentación sobre cómo restringir el inicio de sesión a mi aplicación web (que usa OAuth2.0 y API de Google) para aceptar solo solicitudes de autenticación de usuarios con un correo electrónico sobre un nombre de dominio específico o conjunto de nombres de dominio. Me gustaría incluir en la lista blanca en lugar de una lista negra.
¿Alguien tiene sugerencias sobre cómo hacer esto, documentación sobre el método oficialmente aceptado de hacerlo, o un trabajo fácil y seguro?
Para el registro, no conozco ninguna información sobre el usuario hasta que intenten iniciar sesión a través de la autenticación OAuth de Google. Todo lo que recibo es la información básica del usuario y el correo electrónico.
Lado del cliente:
Al usar la función init de auth2
, puede pasar el parámetro hosted_domain
para restringir las cuentas enumeradas en la ventana emergente de hosted_domain
a aquellas que coincidan con su hosted_domain
. Puede ver esto en la documentación aquí: https://developers.google.com/identity/sign-in/web/reference
Lado del servidor:
Incluso con una lista restringida del lado del cliente, deberá verificar que id_token
coincida con el dominio alojado que especificó. Para algunas implementaciones esto significa verificar el atributo hd
que recibes de google después de verificar el token.
Ejemplo de pila completa:
Código web:
gapi.load(''auth2'', function () {
// init auth2 with your hosted_domain
// only matching accounts will show up in the list or be accepted
var auth2 = gapi.auth2.init({
client_id: "your-client-id.apps.googleusercontent.com",
hosted_domain: ''your-special-domain.com''
});
// setup your signin button
auth2.attachClickHandler(yourButtonElement, {});
// when the current user changes
auth2.currentUser.listen(function (user) {
// if the user is signed in
if (user && user.isSignedIn()) {
// validate the token on your server,
// your server will need to double check that the
// `hd` matches your specified `hosted_domain`;
validateTokenOnYourServer(user.getAuthResponse().id_token)
.then(function () {
console.log(''yay'');
})
.catch(function (err) {
auth2.then(function() { auth2.signOut(); });
});
}
});
});
Código del servidor (usando la biblioteca googles Node.js):
Si no está utilizando Node.js, puede ver otros ejemplos aquí: https://developers.google.com/identity/sign-in/web/backend-auth
const GoogleAuth = require(''google-auth-library'');
const Auth = new GoogleAuth();
const authData = JSON.parse(fs.readFileSync(your_auth_creds_json_file));
const oauth = new Auth.OAuth2(authData.web.client_id, authData.web.client_secret);
const acceptableISSs = new Set(
[''accounts.google.com'', ''https://accounts.google.com'']
);
const validateToken = (token) => {
return new Promise((resolve, reject) => {
if (!token) {
reject();
}
oauth.verifyIdToken(token, null, (err, ticket) => {
if (err) {
return reject(err);
}
const payload = ticket.getPayload();
const tokenIsOK = payload &&
payload.aud === authData.web.client_id &&
new Date(payload.exp * 1000) > new Date() &&
acceptableISSs.has(payload.iss) &&
payload.hd === ''your-special-domain.com'';
return tokenIsOK ? resolve() : reject();
});
});
};
Al definir su proveedor, pase un hash al final con el parámetro ''hd''. Puede leer sobre eso aquí. https://developers.google.com/accounts/docs/OpenIDConnect#hd-param
Por ejemplo, para config / initializers / devise.rb
config.omniauth :google_oauth2, ''identifier'', ''key'', {hd: ''yourdomain.com''}
Así que tengo una respuesta para ti. En la solicitud Oauth puede agregar "hd = domain.com" y restringirá la autenticación a los usuarios de ese dominio (no sé si puede hacer varios dominios). Puede encontrar el parámetro hd documentado here
Estoy usando las bibliotecas de google api desde aquí: http://code.google.com/p/google-api-php-client/wiki/OAuth2 así que tuve que editar manualmente el archivo /auth/apiOAuth2.php a este :
public function createAuthUrl($scope) {
$params = array(
''response_type=code'',
''redirect_uri='' . urlencode($this->redirectUri),
''client_id='' . urlencode($this->clientId),
''scope='' . urlencode($scope),
''access_type='' . urlencode($this->accessType),
''approval_prompt='' . urlencode($this->approvalPrompt),
''hd=domain.com''
);
if (isset($this->state)) {
$params[] = ''state='' . urlencode($this->state);
}
$params = implode(''&'', $params);
return self::OAUTH2_AUTH_URL . "?$params";
}
Editar: sigo trabajando en esta aplicación y encontré esto, que puede ser la respuesta más correcta a esta pregunta. https://developers.google.com/google-apps/profiles/
Esto es lo que hice usando el pasaporte en node.js. profile
es el usuario que intenta iniciar sesión.
//passed, stringified email login
var emailString = String(profile.emails[0].value);
//the domain you want to whitelist
var yourDomain = ''@google.com'';
//check the x amount of characters including and after @ symbol of passed user login.
//This means ''@google.com'' must be the final set of characters in the attempted login
var domain = emailString.substr(emailString.length - yourDomain.length);
//I send the user back to the login screen if domain does not match
if (domain != yourDomain)
return done(err);
Luego solo crea la lógica para buscar varios dominios en lugar de solo uno. Creo que este método es seguro porque 1. el símbolo ''@'' no es un carácter válido en la primera o segunda parte de una dirección de correo electrónico. No pude engañar a la función creando una dirección de correo electrónico como mike@[email protected]
2. En un sistema de inicio de sesión tradicional pude, pero esta dirección de correo electrónico nunca podría existir en Google. Si no es una cuenta válida de Google, no puede iniciar sesión.