Oracle Functions : Valider une clé d'API à l'aide de la passerelle d'API

Dans ce tutoriel, vous utiliserez Oracle Functions pour valider une clé d'API transmise à partir d'Oracle API Gateway. Une clé d'API est une méthode simple qui permet de sécuriser une API en exigeant du client qu'il transmette un jeton spécifique. La passerelle peut utiliser le jeton en tant que fonction d'autorisation personnalisée pour valider les demandes. Vous créerez une fonction Python qui valide le jeton et retourne une réponse JSON authentifiée.

Voici les principales tâches :

  • Collecter les informations requises.
  • Créer une application pour votre fonction.
  • Créer une fonction "Hello World!".
  • Convertir votre fonction pour valider la clé d'API.
  • Déployer et tester votre fonction.
  • Créer une passerelle d'API pour votre fonction.
  • Appeler votre fonction à partir d'Internet à l'aide de votre passerelle d'API.
Images illustrant les composants OCI utilisés pour exécuter Oracle Functions.

Pour plus d'informations, voir :

Étapes préliminaires

Pour suivre ce tutoriel, vous devez disposer des éléments suivants :

Exigences en matière de compte OCI
Exigences en matière de logiciel

Interface de ligne de commande Oracle

Oracle Cloud Shell

  • Si vous utilisez Cloud Shell, les logiciels répertoriés dans la liste précédente sont déjà installés.

1. Collecter les informations requises

Collectez toutes les informations dont vous aurez besoin pour suivre le tutoriel. Copiez les informations suivantes dans votre bloc-notes.

Obtenir des informations sur le compartiment

Pour créer un compartiment, voir Créer un compartiment. Une fois votre compartiment créé, enregistrez son OCID et son nom.

Pour obtenir l'OCID du compartiment à partir d'un compartiment existant :

  1. Ouvrez le menu de navigation et cliquez sur Identité et sécurité. Sous Identité, cliquez sur Compartiments.
  2. Sélectionnez votre compartiment.
  3. Cliquez sur le lien Copier pour le champ OCID.

Enregistrez l'OCID et le nom du compartiment.

Informations collectées

Notez les informations suivantes pour le tutoriel.

  • Nom du compartiment : <your-compartment-name>

    Exemple : mon compartiment

  • ID compartiment : <your-compartment-OCID>

    Exemple : ocid1.compartment.oc1.aaaaaaa...

  • Nom du VCN : <your-vcn-name>

    Exemple : mon VCN

    Ouvrez le menu de navigation et cliquez successivement sur Service de réseau et Réseaux en nuage virtuels.

  • Nom du sous-réseau public du réseau VCN : <Public-Subnet-your-vcn-name>

    Exemple : Public-Subnet-my-vcn

    Ouvrez le menu de navigation et cliquez successivement sur Service de réseau et Réseaux en nuage virtuels. Cliquez sur le VCN que vous avez créé.

2. Effectuer la configuration requise

Effectuez toute la configuration nécessaire pour le tutoriel.

Créer une application Oracle Functions

Pour créer une application, procédez de la façon suivante.

  1. Ouvrez le menu de navigation et cliquez sur Services de développement. Sous Fonctions, cliquez sur Applications.
  2. Sélectionnez votre compartiment dans la liste déroulante Compartiments.
  3. Cliquez sur Créer une application.
  4. Complétez le formulaire.
    • Nom : <your-app-name>
    • VCN : <your-vcn-name>
    • Sous-réseaux : <Public-Subnet-your-vcn-name>
  5. Cliquez sur Créer.

Votre application est créée.

Configurer une règle de trafic entrant pour HTTPS
  1. Ouvrez le menu de navigation et cliquez successivement sur Service de réseau et Réseaux en nuage virtuels.
  2. Cliquez sur le nom du VCN que vous avez utilisé pour votre application Oracle Functions.
  3. Maintenant que votre nouveau VCN est affiché, cliquez sur le lien de sous-réseau Public.

    Les informations sur le sous-réseau public s'affichent avec les listes de sécurité au bas de la page.

  4. Cliquez sur le lien Liste de sécurité par défaut ou sur le lien de liste de sécurité approprié.

    Les règles de trafic entrant par défaut pour votre VCN s'affichent.

  5. Cliquez sur Ajouter des règles de trafic entrant.

    Une boîte de dialogue Ajouter des règles de trafic entrant s'affiche.

  6. Entrez les informations suivantes pour la règle de trafic entrant. Une fois toutes les données entrées, cliquez sur Ajouter des règles de trafic entrant

    Définissez la règle de trafic entrant comme suit :

    • Sans état : Coché
    • Type de source : CIDR
    • CIDR source : 0.0.0.0/0
    • Protocole IP : TCP
    • Intervalle de ports sources : (Laissez vide)
    • Intervalle de ports de destination : 443
    • Description : VCN pour les applications

    Après que vous avez cliqué sur Ajouter une règle de trafic entrant, les connexions HTTPS à votre sous-réseau public sont autorisées.

Configurer une politique de configuration pour l'accès de la passerelle d'API aux fonctions

À présent, configurez une politique qui permet à la passerelle d'API d'appeler des fonctions.

Commencez par créer un groupe dynamique pour la passerelle d'API.

  1. Ouvrez le menu de navigation et cliquez sur Identité et sécurité. Sous Identité, cliquez sur Groupes dynamiques.
  2. Cliquez sur Créer un groupe dynamique.
  3. Indiquez les informations suivantes pour définir votre groupe dynamique.
    • Nom : <name-for-your-dynamic-group>
    • Sous Règles de correspondance, utilisez Règle 1 : <the-rule-text>

    Voici le nom d'exemple et la règle que vous devez entrer.

    • Nom : api-gtw-func-dynamic-group
    • Sous Règles de correspondance, utilisez Règle 1 : Tout {resource.type = 'ApiGateway', resource.compartment.id = 'ocid1.compartment.<your-compartment-OCID>'}
  4. Cliquez sur Créer.

À présent, créez la politique pour la passerelle d'API.

  1. Ouvrez le menu de navigation et cliquez sur Identité et sécurité. Sous Identité, cliquez sur Politiques.
  2. Cliquez sur Créer une politique.
  3. Pour définir votre politique, entrez les informations suivantes.
    • Nom : <name-for-your-policy>
    • Description : <description-for policy>
    • compartiment : <name-of-functions-compartment>

    Pour la section Générateur de politiques :

    • Cliquez sur Afficher l'éditeur manuel.
    • Entrez votre politique dans la zone de texte, par exemple :
      Allow dynamic-group  api-gtw-func-dynamic-group to use functions-family in compartment <your-compartment-name>
      Note

      Le dernier paramètre est le nom et non l'OCID du compartiment.
  4. Cliquez sur Créer.

Vous avez créé une politique pour permettre à la passerelle d'API d'utiliser le service des fonctions.

Créer une fonction Python "Hello World"
  1. Ouvrez une fenêtre de terminal.
  2. Créez un répertoire dans lequel stocker vos fonctions et accédez à ce répertoire.
    mkdir my-dir-name
    cd my-dir-name                        
                         
  3. Créez une fonction Python "Hello World" avec Fn.
    fn init --runtime python my-func-name

    Cette commande crée un répertoire nommé my-func-name contenant la fonction et des fichiers de configuration.

  4. Accédez au répertoire.
  5. Déployez la fonction.
    fn -v deploy --app your-app-name

    Divers messages s'affichent au fur et à mesure que les images Docker sont créées, poussées vers OCIR, puis déployées dans Oracle Functions.

  6. Appelez la fonction.
    fn invoke your-app-name my-func-name

    Retourne : {"message": "Hello World"}

  7. Appelez la fonction avec un paramètre.
    echo -n '{"name":"Bob"}' | fn invoke your-app-name my-func-name

    Retourne : {"message": "Hello Bob"}

3. Créer une passerelle d'API

Pour appeler votre fonction, créez une passerelle d'API.

Créer la passerelle d'API

Pour créer une passerelle d'API :

  1. Ouvrez le menu de navigation et cliquez sur Services de développement. Sous Gestion d'API, cliquez sur Passerelles.
  2. Sélectionnez votre compartiment dans la liste déroulante Compartiments.
  3. Cliquez sur Créer une passerelle
  4. Indiquez les informations suivantes pour définir votre passerelle d'API.
    • Nom : <your-gateway-name>
    • Type : <Public>
    • compartiment : <your-compartment-name>
    • Réseau en nuage virtuel dans <your-vcn-name>: <select-your-vcn>
    • Sous-réseau dans <your-compartment-name: <your-public-subnet-name>
  5. Cliquez sur Créer. Attendez quelques minutes que votre passerelle d'API soit créée.
Créer un déploiement d'API pour votre passerelle

À présent, créez un déploiement pour votre passerelle d'API.

  1. Cliquez sur Déploiements dans la section Ressources située dans la partie gauche de l'écran.
  2. Cliquez sur Créer un déploiement.
  3. Assurez-vous que À partir de zéro est sélectionné pour le type de déploiement.
  4. Pour définir votre déploiement, renseignez la section Informations de base.
    • Nom : <your-deployment-name>
    • Préfixe de chemin (exemple) : /tokens
    • compartiment : <your-compartment-name>
    • Politiques de demande d'API : Utilisez les valeurs par défaut
    • Politiques de journalisation d'API : Utilisez la valeur par défaut Informations
  5. Cliquez sur Suivant. La boîte de dialogue Routes s'affiche avec la valeur Route 1 sélectionnée.
  6. Pour définir votre route, renseignez la section Route 1.
    • Chemin : <your-route-path>

      Exemple : /val-token

    • Modes : GET POST
    • Type : Oracle Functions
    • Application dans <your-compartment-name> : Sélectionnez l'application Oracle Functions que vous avez créée.
    • Nom de la fonction : Sélectionnez la fonction que vous avez créée à la section de configuration.
  7. Cliquez sur Suivant. La boîte de dialogue Vérifier récapitulant les choix que vous avez faits s'affiche.
  8. Cliquez sur Créer. Votre déploiement est créé.
  9. Cliquez sur le lien Déploiements pour votre passerelle. Copiez le point d'extrémité de base pour le déploiement que vous avez créé.

    Par exemple : https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/tokens

Tester votre passerelle d'API

Maintenant que votre passerelle d'API et votre déploiement sont créés, vous pouvez tester votre installation. Créez un script simple pour la commande curl. Pour créer l'URL de curl, ajoutez votre chemin de déploiement à votre point d'extrémité.

  1. Créez le fichier de script : touch gtw01.sh && chmod 755 gtw01.sh
  2. Ajoutez la commande curl au fichier de script :
    #!/bin/bash
    curl <your-api-gateway-endpoint>/val-token
  3. La commande retourne : {"message":"Hello World"}

Vous avez connecté votre passerelle d'API à une fonction Python standard. À présent, vous allez mettre à jour votre fonction Python pour afficher les informations transmises dans une demande HTTP.

4. Mettre à jour la fonction pour valider la clé d'API

À présent, modifiez la fonction Python standard pour valider la clé d'API.

Vérifier le code Python de départ

Si vous examinez la fonction Python standard, elle ressemble à ceci.

import io
import json
import logging

from fdk import response


def handler(ctx, data: io.BytesIO = None):
    name = "World"
    try:
        body = json.loads(data.getvalue())
        name = body.get("name")
    except (Exception, ValueError) as ex:
        logging.getLogger().info('error parsing json payload: ' + str(ex))
    
    logging.getLogger().info("Inside Python Hello World function")
    return response.Response(
       ctx, response_data=json.dumps(
           {"message": "Hello {0}".format(name)}),
       headers={"Content-Type": "application/json"}
    )

Avec ce code comme point de départ, les sections suivantes convertissent la fonction en une fonction Python qui valide une clé d'API et retourne un jeton.

Créer une variable de configuration d'Oracle Functions

Oracle Functions vous permet de stocker les données de configuration dans le contexte disponible dans votre demande. Il est possible de stocker les données de configuration dans une application ou une fonction. La commande suivante stocke la clé d'API dans la configuration de votre application.

  • fn config app <your-app-name> FN_API_KEY ABCD

La chaîne "ABCD" est un exemple de valeur de clé.

Pour plus d'informations sur la définition des valeurs de configuration d'Oracle Functions, voir le tutoriel sur le contexte d'exécution FnProject.

Mettre à jour les ensembles requis et la fonction Handler

Commencez par mettre à jour func.py avec les ensembles requis.

  1. Mettez à jour les énoncés import dans func.py pour la validation des ensembles requis :
    import io
    import json
    import logging
    import datetime
    
    from datetime import timedelta
    from fdk import response
                    

    L'ensemble datetime sert à définir un délai d'expiration pour le jeton retourné.

  2. Retirez le corps principal de la fonction. La méthode response et le code connexe seront ajoutés à nouveau au fur et à mesure.
    import io
    import json
    import logging
    import datetime
    
    from datetime import timedelta
    from fdk import response
                            
    
    def handler(ctx, data: io.BytesIO = None):                
    

À présent, vous pouvez mettre à jour la fonction avec le code de validation.

Ajouter un code de validation à la fonction

À présent, ajoutez du code pour valider la clé d'API et retourner un jeton dans la réponse. Voici le code avec des commentaires.

import io
import json
import logging
import datetime

from datetime import timedelta
from fdk import response

def handler(ctx, data: io.BytesIO = None):
    auth_token = "invalid"
    token = "invalid"
    apiKey = "invalid"
    expiresAt = (datetime.datetime.utcnow() + timedelta(seconds=60)).replace(tzinfo=datetime.timezone.utc).astimezone().replace(microsecond=0).isoformat()
    
    try:
        auth_token = json.loads(data.getvalue())
        token = auth_token.get("token")
        
        app_context = dict(ctx.Config())
        apiKey = app_context['FN_API_KEY']
        
        if token == apiKey:
            return response.Response(
                ctx, 
                status_code=200, 
                response_data=json.dumps({"active": True, "principal": "foo", "scope": "bar", "clientId": "1234", "expiresAt": expiresAt, "context": {"username": "wally"}})
            )
    
    except (Exception, ValueError) as ex:
        logging.getLogger().info('error parsing json payload: ' + str(ex))
        pass
    
    return response.Response(
        ctx, 
        status_code=401, 
        response_data=json.dumps({"active": False, "wwwAuthenticate": "API-key"})
    )
  • La fonction handler reçoit des informations système sur la demande courante au moyen des paramètres ctx et data.
  • La fonction suppose que FN_API_KEY est défini dans la configuration de l'application. Ensuite, la fonction compare la valeur de configuration à la valeur de jeton envoyée à partir de la demande POST curl : -d '{"token":"ABCD"}'.
  • Si les valeurs correspondent, un message JSON de validation est retourné. Dans le cas contraire, un code 401 est retourné avec les données d'erreur JSON.

Le code de fonction est terminé. À présent, vous pouvez tester la fonction.

Tester votre fonction
  1. Redéployez la fonction mise à jour.
  2. Appelez la fonction pour vous assurer qu'elle fonctionne.
  3. Mettez à jour le script gtw01.sh pour transmettre les données POST au script.
    /bin/bash
    curl -X POST -d '{"token":"ABCD"}' https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/tokens/val-token
  4. Exécutez le script : gtw01.sh | jq
  5. Si les clés d'API correspondent, la sortie du script ressemble à ceci :
    {
        "active": true,
        "principal": "foo",
        "scope": "bar",
        "clientId": "1234",
        "expiresAt": "2020-12-16T22:48:50+00:00",
        "context": {
        "username": "wally"
        }
    }

    Si les clés d'API ne correspondent pas, un message d'erreur est retourné.

    {
        "active": false,
        "wwwAuthenticate": "API-key"
    }                        
                        

    Vous pouvez télécharger le code source complet de la fonction à partir du site des échantillons pour Oracle Functions.

Félicitations, vous avez converti la fonction Python standard en une nouvelle fonction qui valide une clé d'API. La fonction montre comment des données peuvent être transmises à la passerelle d'API et traitées dans une fonction.