Passer au contenu principal
Ce tutoriel explique comment appeler votre propre API à partir d’une application native, mobile ou monopage à l’aide du flux de code d’autorisation avec PKCE. Pour savoir comment fonctionne ce flux et pourquoi vous devriez l’utiliser, consultez Flux de code d’autorisation avec Proof Key for Code Exchange (PKCE). Pour apprendre à ajouter la connexion à votre application native, mobile ou monopage, consultez Ajouter la connexion à l’aide du flux de code d’autorisation avec PKCE.
Auth0 facilite l’implémentation du flux de code d’autorisation avec Proof Key for Code Exchange (PKCE) dans votre application à l’aide des options suivantes :

Prérequis

Avant de commencer ce tutoriel :
  • Enregistrez l’application dans Auth0.
    • Sélectionnez Application Type : Native ou application monopage, selon le type de votre application.
    • Ajoutez {yourCallbackUrl} comme Allowed Callback URL. Le format de l’URL de rappel varie selon le type de votre application et votre plateforme. Pour en savoir plus sur le format propre à votre type d’application et à votre plateforme, consultez nos Quickstarts Native/Mobile et Quickstarts application monopage.
    • Assurez-vous que Grant Types inclut Authorization Code. Pour savoir comment faire, consultez Update Grant Types.
    • Si vous voulez que votre application puisse utiliser des Jetons d’actualisation, assurez-vous que Grant Types inclut Jeton d’actualisation. Pour savoir comment faire, consultez Update Grant Types. Pour en savoir plus sur les Jetons d’actualisation, consultez Refresh Tokens.
  • Enregistrez votre API dans Auth0
    • Si vous voulez que votre API reçoive des Jetons d’actualisation afin de pouvoir obtenir de nouveaux jetons lorsque les précédents expirent, activez Allow Offline Access.

Étapes

  1. Créer le vérificateur de code: Générez un code_verifier qui sera envoyé à Auth0 pour demander des jetons.
  2. Créer le défi de code: Générez un code_challenge à partir du code_verifier, qui sera envoyé à Auth0 pour demander un authorization_code.
  3. Autoriser l’utilisateur: Demandez l’autorisation de l’utilisateur, puis redirigez-le vers votre application avec un authorization_code.
  4. Demander des jetons: Échangez votre authorization_code et votre code_verifier contre des jetons.
  5. Appeler l’API: Utilisez le Jeton d’accès récupéré pour appeler votre API.
  6. Actualiser les jetons: Utilisez un Jeton d’actualisation pour demander de nouveaux jetons lorsque les jetons existants expirent.
Facultatif : Explorer des exemples de cas d’utilisation.

Créer un vérificateur de code

Créez un code_verifier, c’est-à-dire une clé générée aléatoirement de manière cryptographiquement sûre et encodée en Base64, qui sera ensuite envoyée à Auth0 pour demander des jetons.

Exemple JavaScript

// Dépendance : module crypto de Node.js
// https://nodejs.org/api/crypto.html#crypto_crypto
function base64URLEncode(str) {
    return str.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}
var verifier = base64URLEncode(crypto.randomBytes(32));

Exemple en Java

// Dépendance : Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/
// Importer la classe Base64.
// import org.apache.commons.codec.binary.Base64;
SecureRandom sr = new SecureRandom();
byte[] code = new byte[32];
sr.nextBytes(code);
String verifier = Base64.getUrlEncoder().withoutPadding().encodeToString(code);

Exemple Android

// See https://developer.android.com/reference/android/util/Base64
// Importer la classe Base64
// import android.util.Base64;
SecureRandom sr = new SecureRandom();
byte[] code = new byte[32];
sr.nextBytes(code);
String verifier = Base64.encodeToString(code, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);

Exemple en Swift 5

var buffer = [UInt8](repeating: 0, count: 32)
_ = SecRandomCopyBytes(kSecRandomDefault, buffer.count, &buffer)
let verifier = Data(buffer).base64EncodedString()
    .replacingOccurrences(of: "+", with: "-")
    .replacingOccurrences(of: "/", with: "_")
    .replacingOccurrences(of: "=", with: "")

Exemple en Objective-C

NSMutableData *data = [NSMutableData dataWithLength:32];
int result __attribute__((unused)) = SecRandomCopyBytes(kSecRandomDefault, 32, data.mutableBytes);
NSString *verifier = [[[[data base64EncodedStringWithOptions:0]
                        stringByReplacingOccurrencesOfString:@"+" withString:@"-"]
                        stringByReplacingOccurrencesOfString:@"/" withString:@"_"]
                        stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]];

Créer le défi de code

Générez un code_challenge à partir du code_verifier, qui sera envoyé à Auth0 afin de demander un authorization_code.

Exemple JavaScript

// Dépendance : module crypto de Node.js
// https://nodejs.org/api/crypto.html#crypto_crypto
function sha256(buffer) {
    return crypto.createHash('sha256').update(buffer).digest();
}
var challenge = base64URLEncode(sha256(verifier));

Exemple en Java

// Dépendance : Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/
// Importer la classe Base64.
// import org.apache.commons.codec.binary.Base64;
byte[] bytes = verifier.getBytes("US-ASCII");
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(bytes, 0, bytes.length);
byte[] digest = md.digest();
String challenge = Base64.encodeBase64URLSafeString(digest);

Exemple en Swift 5

import CommonCrypto

// ...

guard let data = verifier.data(using: .utf8) else { return nil }
var buffer = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
_ = data.withUnsafeBytes {
    CC_SHA256($0.baseAddress, CC_LONG(data.count), &buffer)
}
let hash = Data(buffer)
let challenge = hash.base64EncodedString()
    .replacingOccurrences(of: "+", with: "-")
    .replacingOccurrences(of: "/", with: "_")
    .replacingOccurrences(of: "=", with: "")

Exemple en Objective-C

// Dépendance : bibliothèque Apple Common Crypto
// http://opensource.apple.com//source/CommonCrypto
u_int8_t buffer[CC_SHA256_DIGEST_LENGTH * sizeof(u_int8_t)];
memset(buffer, 0x0, CC_SHA256_DIGEST_LENGTH);
NSData *data = [verifier dataUsingEncoding:NSUTF8StringEncoding];
CC_SHA256([data bytes], (CC_LONG)[data length], buffer);
NSData *hash = [NSData dataWithBytes:buffer length:CC_SHA256_DIGEST_LENGTH];
NSString *challenge = [[[[hash base64EncodedStringWithOptions:0]
                         stringByReplacingOccurrencesOfString:@"+" withString:@"-"]
                         stringByReplacingOccurrencesOfString:@"/" withString:@"_"]
                         stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]];

Autoriser l’utilisateur

Une fois que vous avez créé le code_verifier et le code_challenge, vous devez obtenir l’autorisation de l’utilisateur. Il s’agit techniquement du début du , et cette étape peut inclure un ou plusieurs des processus suivants :
  • Authentifier l’utilisateur;
  • Rediriger l’utilisateur vers un pour prendre en charge l’authentification;
  • Vérifier la présence de sessions d’authentification unique (SSO) actives;
  • Obtenir le consentement de l’utilisateur pour le niveau d’accès demandé, à moins que ce consentement n’ait déjà été accordé.
Pour autoriser l’utilisateur, votre application doit le rediriger vers l’URL d’autorisation, en incluant le code_challenge généré à l’étape précédente ainsi que la méthode utilisée pour générer le code_challenge.

Exemple d’URL d’autorisation

Paramètres
Notez que, pour autoriser un utilisateur lors de l’appel à une API personnalisée, vous :
  • devez inclure un paramètre
  • pouvez inclure des scopes supplémentaires pris en charge par l’API cible
Parameter NameDescription
response_typeIndique le type d’identifiant qu’Auth0 renverra (code ou token). Pour ce flux, la valeur doit être code.
code_challengeDéfi généré à partir du code_verifier.
code_challenge_methodMéthode utilisée pour générer le défi (par ex., S256). La spécification PKCE définit deux méthodes, S256 et plain ; la première est utilisée dans cet exemple et est la seule prise en charge par Auth0, puisque la seconde est déconseillée.
client_idL’ID client de votre application. Vous trouverez cette valeur dans les paramètres de l’application.
redirect_uriL’URL vers laquelle Auth0 redirigera le navigateur une fois que l’utilisateur aura accordé l’autorisation. Le code d’autorisation sera disponible dans le paramètre d’URL code. Vous devez spécifier cette URL comme URL de callback valide dans les paramètres de l’application.

Avertissement : Conformément à la spécification OAuth 2.0, Auth0 supprime tout ce qui suit le dièse et ne prend pas en charge les fragments.
scopeLes scopes pour lesquels vous souhaitez demander une autorisation. Ils doivent être séparés par un espace. Vous pouvez demander n’importe lequel des scopes OpenID Connect (OIDC) standard concernant les utilisateurs, comme profile et email, des revendications personnalisées conformes à un format avec espace de noms, ou tout scope pris en charge par l’API cible (par ex., read:contacts). Incluez offline_access pour obtenir un Jeton d’actualisation (assurez-vous que le champ Allow Offline Access est activé dans les paramètres de l’application).
audienceL’identifiant unique de l’API à laquelle votre application mobile veut accéder. Utilisez la valeur Identifier dans l’onglet Settings de l’API que vous avez créée dans le cadre des prérequis de ce tutoriel.
state(recommandé) Chaîne alphanumérique opaque et arbitraire que votre application ajoute à la requête initiale et qu’Auth0 inclut lors de la redirection vers votre application. Pour savoir comment utiliser cette valeur afin d’empêcher les attaques de falsification de requêtes intersites (CSRF), consultez Mitigate CSRF Attacks With State Parameters.
organization(facultatif) ID de l’organisation à utiliser lors de l’authentification d’un utilisateur. Si ce paramètre n’est pas fourni et que votre application est configurée pour Display Organization Prompt, l’utilisateur pourra saisir le nom de l’organisation au moment de l’authentification.
invitation(facultatif) ID du ticket d’invitation de l’organisation. Lorsque vous invitez un membre à une organisation, votre application doit gérer l’acceptation de l’invitation en transmettant les paires clé-valeur invitation et organization lorsque l’utilisateur accepte l’invitation.
Par exemple, votre extrait HTML pour votre URL d’autorisation lors de l’appel à une API pourrait ressembler à ceci :

Réponse

Si tout se passe bien, vous recevrez une réponse HTTP 302. Le code d’autorisation se trouve à la fin de l’URL :
HTTP/1.1 302 Found
Location: {yourCallbackUrl}?code={authorizationCode}&state=xyzABC123

Demander des jetons

Maintenant que vous disposez d’un code d’autorisation, vous devez l’échanger contre des jetons. À l’aide du code d’autorisation extrait (code) à l’étape précédente, vous devrez envoyer une requête POST à l’URL du jeton en y joignant le code_verifier.

Exemple de requête POST à l’URL du jeton

Paramètres
Nom du paramètreDescription
grant_typeDéfinissez cette valeur sur « authorization_code ».
code_verifierLa clé aléatoire générée de façon cryptographiquement sécurisée à la première étape de ce tutoriel.
codeLe authorization_code récupéré à l’étape précédente de ce tutoriel.
client_idL’ID client de votre application. Vous trouverez cette valeur dans les paramètres de l’application.
redirect_uriL’URL de callback valide définie dans les paramètres de votre application. Elle doit correspondre exactement au redirect_uri envoyé à l’URL d’autorisation à l’étape précédente de ce tutoriel. Notez qu’elle doit être encodée en URL.

Réponse

Si tout se passe bien, vous recevrez une réponse HTTP 200 avec un payload contenant les valeurs access_token, refresh_token, id_token et token_type :
{
  "access_token":"eyJz93a...k4laUWw",
  "refresh_token":"GEbRxBN...edjnXbL",
  "id_token":"eyJ0XAi...4faeEoQ",
  "token_type":"Bearer",
  "expires_in":86400
}
Validez vos jetons avant de les enregistrer. Pour savoir comment faire, consultez Valider les ID tokens et Valider les jetons d’accès.
ID tokens contiennent des informations sur l’utilisateur qui doivent être décodées et extraites. Jetons d’accès servent à appeler le point de terminaison /userinfo de l’Authentication API d’Auth0 ou une autre API. Si vous appelez votre propre API, la première chose à faire sera de vérifier le jeton d’accès. Jetons d’actualisation servent à obtenir un nouveau ou un nouvel après l’expiration du précédent. Le refresh_token n’est présent dans la réponse que si vous avez inclus le scope offline_access et activé Allow Offline Access pour votre API dans l’Auth0 Dashboard.
Les jetons d’actualisation doivent être stockés de façon sécuritaire, puisqu’ils permettent à un utilisateur de rester authentifié essentiellement indéfiniment.

Appeler l’API

Pour appeler votre API depuis une application native ou mobile, l’application doit transmettre le Jeton d’accès récupéré comme jeton Bearer dans l’en-tête Authorization de la requête HTTP.

Jetons d’actualisation

Vous avez déjà reçu un jeton d’actualisation si vous avez suivi ce tutoriel et effectué les étapes suivantes :
  • configuré votre API pour autoriser l’accès hors ligne
  • inclus le scope offline_access lorsque vous avez envoyé la demande d’authentification par l’intermédiaire du point de terminaison d’autorisation.
Vous pouvez utiliser le pour obtenir un nouveau jeton d’accès. En général, un utilisateur n’a besoin d’un nouveau jeton d’accès qu’après l’expiration du précédent ou lorsqu’il accède à une nouvelle ressource pour la première fois. Il est déconseillé d’appeler le point de terminaison pour obtenir un nouveau jeton d’accès chaque fois que vous appelez une API, et Auth0 applique des limites de débit qui limiteront le nombre de requêtes au point de terminaison pouvant être exécutées avec le même jeton depuis la même adresse IP. Pour actualiser votre jeton, envoyez une requête POST au point de terminaison /oauth/token de l’Authentication API, en utilisant grant_type=refresh_token.

Exemple de requête POST vers l’URL du jeton

Paramètres
Nom du paramètreDescription
grant_typeDéfinissez-le sur refresh_token.
client_idL’ID client de votre application. Vous trouverez cette valeur dans les paramètres de l’application.
refresh_tokenLe jeton d’actualisation à utiliser.
scope(facultatif) Liste des scopes demandés, délimitée par des espaces. S’il n’est pas envoyé, les scopes d’origine sont utilisés; sinon, vous pouvez demander un ensemble réduit de scopes. Notez que cette valeur doit être encodée dans l’URL.

Réponse

Si tout se passe bien, vous recevrez une réponse HTTP 200 avec un payload contenant un nouvel access_token, sa durée de vie en secondes (expires_in), les valeurs de scope accordées et token_type. Si le scope du jeton initial comprenait openid, la réponse inclura également un nouvel id_token :
{
  "access_token": "eyJ...MoQ",
  "expires_in": 86400,
  "scope": "openid offline_access",
  "id_token": "eyJ...0NE",
  "token_type": "Bearer"
}
Validez vos jetons avant de les enregistrer. Pour savoir comment, consultez Valider les ID tokens et Valider les jetons d’accès.

Exemples de cas d’usage

Personnaliser les jetons

Vous pouvez utiliser Actions pour modifier les scopes renvoyés par les jetons d’accès et/ou ajouter des revendications aux jetons d’accès et aux ID Tokens. (Pour en savoir plus sur Actions, consultez Auth0 Actions. ) Pour ce faire, ajoutez l’Action suivante, qui s’exécutera après l’authentification de l’utilisateur :
exports.onExecutePostLogin = async (event, api) => {
  // Ajouter des revendications personnalisées au jeton d'accès et à l'ID Token
  api.accessToken.setCustomClaim('https://foo/bar', 'value');
  api.idToken.setCustomClaim('https://fiz/baz', 'some other value');

  // Modifier le scope du jeton d'accès
  api.accessToken.addScope('foo');
  api.accessToken.addScope('bar');
};
Les scopes seront disponibles dans le jeton une fois l’Action exécutée.
Auth0 renvoie les informations de profil sous forme de revendications structurées, conformément à la spécification OpenID Connect (OIDC). Cela signifie que les revendications personnalisées ajoutées aux ID tokens ou aux jetons d’accès doivent respecter les directives et restrictions afin d’éviter tout risque de collision.

Consulter l’application exemple : application mobile + API

Pour un exemple d’implémentation, consultez le scénario d’architecture Mobile + API. Cette série de tutoriels s’accompagne d’un exemple de code accessible sur GitHub.

En savoir plus