Funzioni: convalida una chiave API con il gateway API

In questa esercitazione viene utilizzato Oracle Functions per convalidare una chiave API passata da Oracle API Gateway. Una chiave API è un metodo semplice per proteggere un'API richiedendo al client di passare un token specifico. Il gateway può utilizzare il token come responsabile autorizzazioni personalizzato per convalidare le richieste. Si crea una funzione Python che convalida il token e restituisce una risposta JSON autenticata.

I task chiave includono come:

  • Raccogliere le informazioni necessarie.
  • Creare un'applicazione per la funzione.
  • Crea una funzione "Hello World!"
  • Convertire la funzione per convalidare la chiave API.
  • Distribuire e testare la funzione.
  • Creare un gateway API per la funzione
  • Chiama la tua funzione da Internet utilizzando il gateway API.
Le immagini mostrano i componenti OCI utilizzati per eseguire le funzioni Oracle.

Per ulteriori informazioni, vedere:

Prima di iniziare

Per eseguire correttamente questa esercitazione, è necessario che:

Requisiti dell'account OCI
Requisiti software

CLI Oracle

Oracle Cloud Shell

  • Se si utilizza Cloud Shell, la lista di software precedente è già installata.

1. Raccogli informazioni necessarie

Raccogli tutte le informazioni necessarie per completare l'esercitazione. Copiare le seguenti informazioni nel blocco note.

Recupera informazioni sul compartimento

Per creare un compartimento, vedere Creare un compartimento. Dopo aver creato il compartimento, salvare l'OCID e il nome del compartimento.

Per ottenere l'OCID compartimento da un compartimento esistente, effettuare le operazioni riportate di seguito.

  1. Aprire il menu di navigazione e fare clic su Identità e sicurezza. In Identità fare clic su Compartimenti.
  2. Selezionare il compartimento.
  3. Fare clic sul collegamento Copia per il campo OCID.

Salvare l'OCID e il nome del compartimento.

Informazioni raccolte

Assicurarsi di disporre delle seguenti informazioni scritte per l'esercitazione.

  • Nome compartimento: <your-compartment-name>

    Esempio: my-compartment

  • ID compartimento: <your-compartment-OCID>

    Esempio: ocid1.compartment.oc1.aaaaaaa...

  • Nome VCN: <your-vcn-name>

    Esempio: my-vcn

    Aprire il menu di navigazione e fare clic su Rete, quindi fare clic su Reti cloud virtuali.

  • Nome subnet pubblica VCN: <Public-Subnet-your-vcn-name>

    Esempio: Public-Subnet-my-vcn

    Aprire il menu di navigazione e fare clic su Rete, quindi fare clic su Reti cloud virtuali. Fare clic sulla VCN creata.

2. Esegui configurazione richiesta

Eseguire tutta la configurazione necessaria per l'esercitazione.

Crea applicazione funzioni

Per creare un'applicazione, procedere come segue.

  1. Aprire il menu di navigazione e fare clic su Servizi per sviluppatori. In Funzioni, fare clic su Applicazioni.
  2. Selezionare il compartimento dall'elenco a discesa Compartimento.
  3. Fare clic su Create Application.
  4. Compilare i dati del modulo.
    • Nome: <your-app-name>
    • VCN: <your-vcn-name>
    • Subnet: <Public-Subnet-your-vcn-name>
  5. Fare clic su Crea.

L'applicazione è stata creata.

Imposta regola di entrata per HTTPS
  1. Aprire il menu di navigazione e fare clic su Rete, quindi fare clic su Reti cloud virtuali.
  2. Fare clic sul nome della VCN utilizzata per l'applicazione Oracle Functions.
  3. Con la nuova VCN visualizzata, fare clic sul collegamento della subnet Pubblica.

    Le informazioni sulla subnet pubblica vengono visualizzate con gli elenchi di sicurezza nella parte inferiore della pagina.

  4. Fare clic sul collegamento Lista di sicurezza predefinita o sul collegamento appropriato della lista di sicurezza.

    Vengono visualizzate le regole di entrata predefinite per la VCN.

  5. Fare clic su Aggiungi regole di entrata.

    Viene visualizzata la finestra di dialogo Aggiungi regole di entrata.

  6. Compilare la regola di entrata con le seguenti informazioni. Dopo aver immesso tutti i dati, fare clic su Aggiungi regole di entrata

    Compilare la regola di entrata come indicato di seguito.

    • Stateless: controllato
    • Tipo di origine: CIDR
    • CIDR di origine: 0.0.0.0/0
    • Protocollo IP: TCP
    • Intervallo porte di origine: (lasciare vuoto)
    • Intervallo di porte di destinazione: 443
    • Descrizione: VCN per le applicazioni

    Dopo aver fatto clic su Aggiungi regola di entrata, le connessioni HTTPS sono consentite alla subnet pubblica.

Imposta criterio per l'accesso alle funzioni del gateway API

Successivamente, imposta un criterio che consenta al gateway API di richiamare le funzioni.

In primo luogo, creare un gruppo dinamico per il gateway API.

  1. Aprire il menu di navigazione e fare clic su Identità e sicurezza. In Identità fare clic su Gruppi dinamici.
  2. Fare clic su Crea gruppo dinamico.
  3. Inserire le seguenti informazioni per definire il gruppo dinamico.
    • Nome: <name-for-your-dynamic-group>
    • In Regole di corrispondenza utilizzare Regola 1: <the-rule-text>

    Di seguito è riportato il nome di esempio e la regola da compilare.

    • Nome: api-gtw-func-dynamic-group
    • In Regole di corrispondenza utilizzare Regola 1: ALL {resource.type = 'ApiGateway', resource.compartment.id = 'ocid1.compartment.<your-compartment-OCID>'}
  4. Fare clic su Crea.

Ora crea il criterio per il gateway API.

  1. Aprire il menu di navigazione e fare clic su Identità e sicurezza. In Identità fare clic su Criteri.
  2. Fare clic su Create Policy.
  3. Per definire la polizza, inserire le seguenti informazioni.
    • Nome: <name-for-your-policy>
    • Descrizione: <description-for policy>
    • Compartimento: <name-of-functions-compartment>

    Per la sezione Policy Builder:

    • Fare clic su Mostra editor manuale.
    • Immettere il criterio nella casella di testo, ad esempio:
      Allow dynamic-group  api-gtw-func-dynamic-group to use functions-family in compartment <your-compartment-name>
      Nota

      L'ultimo parametro è il nome del compartimento, non l'OCID del compartimento.
  4. Fare clic su Crea.

È stato creato un criterio per consentire al gateway API di utilizzare le funzioni.

Crea funzione Python "Hello World"
  1. Aprire un terminale.
  2. Creare una directory in cui memorizzare le funzioni e passare a tale directory.
    mkdir my-dir-name
    cd my-dir-name                        
                         
  3. Crea una funzione "Hello World" Python con Fn.
    fn init --runtime python my-func-name

    Questo comando crea una directory denominata my-func-name contenente i file di funzione e configurazione.

  4. Passare alla directory.
  5. Distribuire la funzione.
    fn -v deploy --app your-app-name

    Vengono visualizzati vari messaggi quando le immagini Docker vengono create, sottoposte a push in OCIR e infine distribuite in Oracle Functions.

  6. Richiama la funzione.
    fn invoke your-app-name my-func-name

    Restituisce: {"message": "Hello World"}

  7. Richiama la funzione con un parametro.
    echo -n '{"name":"Bob"}' | fn invoke your-app-name my-func-name

    Restituisce: {"message": "Hello Bob"}

3. Creare un gateway API

Per chiamare la tua funzione, crea un gateway API.

Crea gateway API

Per creare un gateway API:

  1. Aprire il menu di navigazione e fare clic su Servizi per sviluppatori. In Gestione API, fare clic su Gateway.
  2. Selezionare il compartimento dall'elenco a discesa Compartimento.
  3. Fare clic su Crea gateway.
  4. Inserire le informazioni riportate di seguito per definire il gateway API.
    • Nome: <your-gateway-name>
    • Tipo: <Public>
    • Compartimento: <your-compartment-name>
    • Rete cloud virtuale in <your-vcn-name>: <select-your-vcn>
    • Subnet in <your-compartment-name: <your-public-subnet-name>
  5. Fare clic su Crea. Attendere alcuni minuti per la creazione del gateway API.
Creare una distribuzione API per il gateway

Successivamente, crea una distribuzione per il gateway API.

  1. Fare clic su Distribuzioni nella sezione Risorse sul lato sinistro della schermata.
  2. Fare clic su Crea distribuzione.
  3. Assicurarsi che l'opzione Da zero sia selezionata per il tipo di distribuzione.
  4. Per definire la distribuzione, compilare la sezione Informazioni di base.
    • Nome: <your-deployment-name>
    • Prefisso percorso (esempio): /tokens
    • Compartimento: <your-compartment-name>
    • Criteri di richiesta API: adotta i valori predefiniti
    • Criteri di registrazione API: prendi il valore predefinito di Information
  5. Fare clic su Successivo. Viene visualizzata la finestra di dialogo Cicli con l'opzione Ciclo 1 selezionata.
  6. Per definire l'instradamento, compilare la sezione Instradamento 1.
    • Percorso: <your-route-path>

      Esempio: /val-token

    • Metodi: GET POST
    • Tipo: Oracle Functions
    • Applicazione in <your-compartment-name>: selezionare l'applicazione Functions creata.
    • Nome funzione: selezionare la funzione creata nella sezione di configurazione.
  7. Fare clic su Successivo. Viene visualizzata la finestra di dialogo Revisione con un riepilogo delle scelte effettuate.
  8. Fare clic su Crea. La distribuzione è stata creata.
  9. Fare clic sul collegamento Distribuzioni per il gateway. Copiare l'endpoint di base per la distribuzione creata.

    Ad esempio: https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/tokens

Test del gateway API

Con il gateway API e la distribuzione creati, è ora possibile eseguire il test dell'installazione. Creare uno script semplice per il comando curl. Per creare l'URL per curl, aggiungere il percorso di distribuzione all'endpoint.

  1. Creare il file di script: touch gtw01.sh && chmod 755 gtw01.sh
  2. Aggiungere il comando curl al file di script:
    #!/bin/bash
    curl <your-api-gateway-endpoint>/val-token
  3. Il comando restituisce: {"message":"Hello World"}

Hai connesso il tuo gateway API a una funzione Python di boiler plate. Successivamente, si aggiorna la funzione Python per visualizzare le informazioni passate in una richiesta HTTP.

4. Aggiorna funzione per convalida chiave API

Successivamente, modificare la funzione Python della piastra di caldaia per convalidare una chiave API.

Rivedi codice Python iniziale

Se si guarda alla funzione piastra caldaia, la funzione Python ha un aspetto simile a questo.

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"}
    )

Utilizzando questo codice come punto di partenza, le sezioni che seguono convertono la funzione in una funzione Python che convalida una chiave API e restituisce un token.

Crea variabile di configurazione funzioni

Oracle Functions consente di memorizzare i dati di configurazione nel contesto disponibile nella richiesta. I dati di configurazione possono essere memorizzati in un'applicazione o in una funzione. Il comando seguente memorizza la chiave API nella configurazione dell'applicazione.

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

La stringa "ABCD" è un valore di chiave di esempio.

Per ulteriori informazioni sull'impostazione dei valori di configurazione delle funzioni, vedere l'esercitazione di Fn Project sul contesto di runtime.

Aggiorna pacchetti richiesti e funzione handler

In primo luogo, aggiornare func.py per i pacchetti richiesti.

  1. Aggiornare le istruzioni import in func.py per la convalida dei pacchetti richiesti:
    import io
    import json
    import logging
    import datetime
    
    from datetime import timedelta
    from fdk import response
                    

    Il pacchetto datetime viene utilizzato per impostare un'ora di scadenza per il token restituito.

  2. Quindi, rimuovere il corpo principale della funzione. Il metodo response e il codice correlato vengono aggiunti di nuovo durante l'avanzamento.
    import io
    import json
    import logging
    import datetime
    
    from datetime import timedelta
    from fdk import response
                            
    
    def handler(ctx, data: io.BytesIO = None):                
    

Ora è possibile aggiornare la funzione con il codice di convalida.

Aggiungi codice di convalida alla funzione

Aggiungere quindi il codice per convalidare la chiave API e restituire un token nella risposta. Ecco il codice con i commenti che seguono.

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 funzione handler riceve informazioni di sistema sulla richiesta corrente tramite i parametri ctx e data.
  • La funzione presuppone che FN_API_KEY sia impostato nella configurazione dell'applicazione. Quindi la funzione confronta il valore di configurazione con il valore del token inviato dalla richiesta POST curl: -d '{"token":"ABCD"}'.
  • Se i valori corrispondono, viene restituito un messaggio JSON di convalida. Se non corrispondono, viene restituito un codice 401 con dati di errore JSON.

Il codice della funzione è completo. Ora è possibile testare la funzione.

Test della funzione
  1. Ridistribuire la funzione aggiornata.
  2. Richiamare la funzione per assicurarsi che la funzione funzioni.
  3. Aggiornare lo script gtw01.sh per passare i dati POST allo script.
    /bin/bash
    curl -X POST -d '{"token":"ABCD"}' https://aaaaa.apigateway.us-ashburn-X.oci.customer-oic.com/tokens/val-token
  4. Eseguire lo script: gtw01.sh | jq
  5. Se le chiavi API corrispondono, l'output dello script è simile al seguente:
    {
        "active": true,
        "principal": "foo",
        "scope": "bar",
        "clientId": "1234",
        "expiresAt": "2020-12-16T22:48:50+00:00",
        "context": {
        "username": "wally"
        }
    }

    Se le chiavi API non corrispondono, viene restituito un messaggio di errore.

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

    È possibile scaricare il codice sorgente completo per la funzione dal sito Esempi di funzioni Oracle qui.

Congratulazioni, avete convertito la funzione Python della piastra della caldaia in una nuova funzione che convalida una chiave API. La funzione dimostra come i dati possono essere passati al gateway API ed elaborati in una funzione.