AWS Cognito
Service d'authentification et d'autorisation sécurisé et évolutif pour vos applications web et mobiles dans le cloud AWS.
Qu'est-ce que AWS Cognito ?
Imaginez que vous avez une application ou un site web qui nécessite que les utilisateurs créent un compte et s'identifient. Vous avez besoin de gérer leurs identités, leurs mots de passe, leurs sessions et vous assurer que seuls les utilisateurs autorisés accèdent à certaines fonctionnalités.
AWS Cognito est comme un portier numérique pour vos applications. Il s'occupe de toute la partie authentification (vérifier l'identité des utilisateurs) et autorisation (déterminer ce qu'ils ont le droit de faire) sans que vous ayez à construire cette infrastructure vous-même.
À quoi sert AWS Cognito ?
Gestion des comptes utilisateurs
Il gère l'inscription, la connexion, la réinitialisation des mots de passe et toute la sécurité associée, comme dans les applications que vous utilisez quotidiennement.
Connexion avec réseaux sociaux
Permet aux utilisateurs de se connecter via Google, Facebook, Apple ou Amazon, sans avoir à créer un compte spécifique à votre application.
En résumé, AWS Cognito offre une solution clé en main pour la gestion des identités et des accès, tout en respectant les standards de sécurité les plus élevés. Cela permet aux développeurs de se concentrer sur les fonctionnalités principales de leur application plutôt que sur l'infrastructure d'authentification.
Fonctionnement technique
AWS Cognito est composé de deux services principaux : User Pools et Identity Pools, qui peuvent être utilisés ensemble ou séparément selon les besoins de l'application.
Les concepts fondamentaux
User Pools
Les User Pools sont des annuaires d'utilisateurs qui offrent des fonctionnalités d'inscription et de connexion pour les applications web et mobiles. Ils gèrent l'ensemble du cycle de vie des utilisateurs et fournissent des tokens JWT (JSON Web Tokens) pour l'authentification.
- Gestion complète des utilisateurs et attributs personnalisables
- Politiques de mot de passe et mécanismes de sécurité configurable
- Authentification multi-facteurs (MFA)
- Fédération d'identité avec des providers sociaux et d'entreprise
- Flux d'authentification personnalisables avec des Lambda Triggers
Identity Pools
Les Identity Pools (Federated Identities) permettent d'accorder aux utilisateurs un accès temporaire et limité aux services AWS directement depuis les applications clientes. Ils traduisent les identités en informations d'identification AWS.
- Accès sécurisé aux services AWS depuis le code client
- Intégration avec des User Pools et des fournisseurs d'identité externes
- Attribution de rôles IAM basés sur l'identité de l'utilisateur
- Prise en charge des utilisateurs authentifiés et anonymes
- Contrôle d'accès précis aux ressources AWS
Flux d'authentification
Cognito prend en charge différents flux d'authentification conformes aux normes industrielles OAuth 2.0 et OpenID Connect.
- Authorization Code Grant : Idéal pour les applications web côté serveur
- Implicit Grant : Pour les applications SPA sans backend
- Client Credentials : Pour les communications entre services
- Secure Remote Password (SRP) : Authentification sans transmission du mot de passe
- Custom Authentication Flows : Via les Lambda Triggers
Intégration avec les services AWS
Cognito s'intègre nativement avec de nombreux services AWS pour créer des applications complètes et sécurisées.
API Gateway : Autorisation de requêtes API basées sur JWT
- AppSync : Contrôle d'accès pour les API GraphQL
S3 : Accès au stockage basé sur l'identité
Lambda : Triggers pour personnaliser les flux d'authentification
CloudFront : Restriction d'accès au contenu distribué
Implémentation technique
Voyons maintenant comment mettre en place un système d'authentification avec AWS Cognito en utilisant le SDK AWS et Amplify.
1. Configuration d'un User Pool
Voici comment créer et configurer un User Pool programmatiquement avec le SDK AWS :
// Configuration d'un User Pool avec AWS SDK v3
const { CognitoIdentityProviderClient, CreateUserPoolCommand } = require("@aws-sdk/client-cognito-identity-provider");
const client = new CognitoIdentityProviderClient({ region: "eu-west-1" });
async function createUserPool() {
try {
const command = new CreateUserPoolCommand({
PoolName: "MyAppUserPool",
Policies: {
PasswordPolicy: {
MinimumLength: 8,
RequireUppercase: true,
RequireLowercase: true,
RequireNumbers: true,
RequireSymbols: true
}
},
AutoVerifiedAttributes: ["email"],
Schema: [
{
Name: "email",
Required: true,
Mutable: true
},
{
Name: "name",
Required: true,
Mutable: true
}
],
MfaConfiguration: "OPTIONAL",
EmailConfiguration: {
EmailSendingAccount: "COGNITO_DEFAULT"
},
AdminCreateUserConfig: {
AllowAdminCreateUserOnly: false
}
});
const response = await client.send(command);
console.log("User Pool créé avec succès:", response);
return response;
} catch (error) {
console.error("Erreur lors de la création du User Pool:", error);
throw error;
}
}
2. Inscription et gestion des utilisateurs
Avec AWS Amplify, l'intégration dans une application front-end devient simple :
// Inscription d'un utilisateur avec AWS Amplify
import { Auth } from 'aws-amplify';
// Configuration d'Amplify (généralement dans le fichier principal de l'application)
Auth.configure({
region: 'eu-west-1',
userPoolId: 'eu-west-1_xYzAbCdE',
userPoolWebClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
authenticationFlowType: 'USER_SRP_AUTH'
});
// Fonction d'inscription d'un utilisateur
async function signUpUser(username, password, email, name) {
try {
const { user } = await Auth.signUp({
username,
password,
attributes: {
email,
name
}
});
console.log("Inscription réussie:", user);
return user;
} catch (error) {
console.error("Erreur lors de l'inscription:", error);
throw error;
}
}
// Confirmation de l'inscription (validation du code reçu par email)
async function confirmSignUp(username, code) {
try {
await Auth.confirmSignUp(username, code);
console.log("Inscription confirmée avec succès");
return true;
} catch (error) {
console.error("Erreur lors de la confirmation:", error);
throw error;
}
}
3. Authentification des utilisateurs
Processus d'authentification complet avec gestion des tokens et des sessions :
// Authentification d'un utilisateur avec AWS Amplify
import { Auth } from 'aws-amplify';
// Connexion de l'utilisateur
async function signInUser(username, password) {
try {
const user = await Auth.signIn(username, password);
// Gestion de l'authentification multi-facteurs si activée
if (user.challengeName === 'SMS_MFA' || user.challengeName === 'SOFTWARE_TOKEN_MFA') {
// Vous devrez demander le code MFA à l'utilisateur
// puis appeler Auth.confirmSignIn(user, code, mfaType)
return { user, requiresMFA: true };
}
console.log("Connexion réussie:", user);
// Récupération des tokens JWT
const session = user.signInUserSession;
const idToken = session.idToken.jwtToken;
const accessToken = session.accessToken.jwtToken;
return { user, idToken, accessToken, requiresMFA: false };
} catch (error) {
console.error("Erreur lors de la connexion:", error);
throw error;
}
}
// Récupération de l'utilisateur courant
async function getCurrentUser() {
try {
const user = await Auth.currentAuthenticatedUser();
console.log("Utilisateur actuel:", user);
return user;
} catch (error) {
console.log("Aucun utilisateur connecté");
return null;
}
}
// Déconnexion
async function signOutUser() {
try {
await Auth.signOut();
console.log("Déconnexion réussie");
return true;
} catch (error) {
console.error("Erreur lors de la déconnexion:", error);
throw error;
}
}
4. Personnalisation avec Lambda Triggers
Les Lambda Triggers permettent de personnaliser le comportement de Cognito à différentes étapes :
// Exemple de Lambda Trigger pour pré-inscription Cognito
exports.handler = async (event, context) => {
// Événement de pré-inscription
if (event.triggerSource === "PreSignUp_SignUp") {
// Récupération des attributs de l'utilisateur
const { email, name } = event.request.userAttributes;
// Vérification du domaine de l'email (par exemple, pour une application d'entreprise)
if (email.split('@')[1] !== 'entreprise.com') {
throw new Error("Seules les adresses email d'entreprise sont autorisées");
}
// Auto-validation de l'email pour éviter l'étape de confirmation (à utiliser avec précaution)
event.response.autoConfirmUser = true;
// Si vous avez configuré l'email comme attribut à vérifier
if (event.request.userAttributes.hasOwnProperty("email")) {
event.response.autoVerifyEmail = true;
}
// Journalisation de l'événement
console.log(`Pré-inscription réussie pour ${email}`);
}
// Retourne l'événement modifié à Cognito
return event;
};
5. Intégration avec API Gateway
Création d'une API sécurisée par Cognito avec AWS CDK :
// Configuration de l'intégration d'Amazon API Gateway avec Cognito
// Dans un projet AWS CDK (TypeScript)
import * as cdk from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as cognito from 'aws-cdk-lib/aws-cognito';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { Construct } from 'constructs';
export class CognitoApiGatewayStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Création du User Pool Cognito
const userPool = new cognito.UserPool(this, 'UserPool', {
userPoolName: 'api-user-pool',
selfSignUpEnabled: true,
autoVerify: { email: true },
standardAttributes: {
email: { required: true, mutable: true },
name: { required: true, mutable: true }
},
passwordPolicy: {
minLength: 8,
requireLowercase: true,
requireUppercase: true,
requireDigits: true,
requireSymbols: true
}
});
// Création du User Pool Client
const userPoolClient = userPool.addClient('ApiClient', {
userPoolClientName: 'api-client',
generateSecret: false,
authFlows: {
userPassword: true,
userSrp: true
},
oAuth: {
flows: { implicitCodeGrant: true },
scopes: [cognito.OAuthScope.OPENID, cognito.OAuthScope.EMAIL, cognito.OAuthScope.PROFILE],
callbackUrls: ['https://example.com/callback', 'http://localhost:3000/callback']
}
});
// Création d'une fonction Lambda pour l'API
const apiHandler = new lambda.Function(this, 'ApiHandler', {
runtime: lambda.Runtime.NODEJS_16_X,
code: lambda.Code.fromAsset('lambda'),
handler: 'api.handler'
});
// Création de l'API Gateway
const api = new apigateway.RestApi(this, 'ProtectedApi', {
restApiName: 'Protected API',
description: 'API protégée par Cognito'
});
// Création d'un autorisateur Cognito
const authorizer = new apigateway.CognitoUserPoolsAuthorizer(this, 'ApiAuthorizer', {
cognitoUserPools: [userPool]
});
// Ajout d'une ressource et une méthode à l'API
const resource = api.root.addResource('protected');
resource.addMethod('GET', new apigateway.LambdaIntegration(apiHandler), {
authorizer: authorizer,
authorizationType: apigateway.AuthorizationType.COGNITO
});
// Variables de sortie pour référence
new cdk.CfnOutput(this, 'UserPoolId', {
value: userPool.userPoolId
});
new cdk.CfnOutput(this, 'UserPoolClientId', {
value: userPoolClient.userPoolClientId
});
new cdk.CfnOutput(this, 'ApiEndpoint', {
value: api.url
});
}
}
Avantages techniques
- Sécurité native : HTTPS, hachage de mots de passe, conformité aux normes industrielles
- Haute disponibilité : Service entièrement géré avec SLA de 99,9%
- Évolutivité : Gestion de millions d'utilisateurs sans configuration spéciale
- Flexibilité : Supports multiples plateformes et langages via SDKs
- Coût optimisé : Facturation par utilisateur actif mensuel, avec niveau gratuit
- Maintenance réduite : Pas de serveurs à gérer ou de mises à jour de sécurité
Cas d'usage
Applications mobiles B2C
Les applications destinées au grand public qui nécessitent une inscription et une connexion simples, avec support des identités sociales pour une adoption rapide.
Applications d'entreprise
Intégration avec les systèmes d'authentification d'entreprise existants via SAML ou OpenID Connect, permettant un accès SSO (Single Sign-On) sécurisé.
API sécurisées
Sécurisation des API REST ou GraphQL avec une autorisation basée sur les tokens JWT, permettant un contrôle d'accès précis aux ressources et aux opérations.
Stockage client sécurisé
Utilisation des Identity Pools pour permettre aux applications clientes d'accéder directement aux ressources AWS comme S3, DynamoDB ou autres services, avec des permissions précises.
Architecture de référence
Une architecture typique d'application cloud sécurisée avec AWS Cognito comprend généralement :
- Frontend : Application
React/Angular/Vue utilisant AWS Amplify pour l'authentification
- Backend sans serveur :
API Gateway +
Lambda protégées par des autorisateurs Cognito
- Base de données :
DynamoDB avec contrôle d'accès précis via
IAM et Cognito
- Stockage :
S3 avec accès direct depuis le client pour les fichiers de l'utilisateur
- Diffusion de contenu :
CloudFront avec OAI pour du contenu sécurisé
Ressources complémentaires
Toutes les compétencesDocumentation officielle
Guide complet pour comprendre et implémenter AWS Cognito
Autorisations précises
Guide sur la mise en place d'autorisations fines avec Cognito, API Gateway et IAM
AWS Amplify Auth
Intégration simplifiée de Cognito dans les applications Web et mobiles avec Amplify