Sécuriser Google Cloud Endpoints avec Auth0
Google Cloud Endpoints (GCE) est un système de gestion d’API offrant des fonctionnalités pour vous aider à créer, maintenir et sécuriser vos API. GCE utilise OpenAPI pour définir les points de terminaison, les entrées et les sorties, les erreurs et la description de la sécurité de votre API.
Pour plus d’informations sur la spécification OpenAPI, voir le référentiel de spécification OpenAPI sur GitHub.
Ce tutoriel explique comment sécuriser Google Cloud Endpoints avec Auth0.
Prérequis
Avant de commencer, vous aurez besoin d’une API GCE déployée. Si vous n’avez pas encore créé d’API, suivez le Guide de démarrage rapide de Cloud Endpoints qui se trouve dans la documentation de Google.
Le guide de démarrage rapide vous guidera à travers la création d’une API GCE simple avec un seul point de terminaison, /airportName
, qui renvoie le nom d’un aéroport à partir de son code IATA de trois lettres.
curl --request GET \
--url 'https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO'
Was this helpful?
var client = new RestClient("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.get("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'GET',
url: 'https://%7ByourGceProject%7D.appspot.com/airportName',
params: {iataCode: 'SFO'}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
conn.request("GET", "%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let request = NSMutableURLRequest(url: NSURL(string: "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Définir l’API dans Auth0
Allez dans Tableau de bord Auth0 > Applications > API, et créez une nouvelle API.

Notez l’identifiant d’audience de l’API (http://google_api
dans la capture d’écran ci-dessus) à utiliser à l’étape suivante.
Mettre à jour la configuration de l’API
Ensuite, nous mettrons à jour le fichier de configuration OpenAPI pour l’API GCE. Pour l’exemple d’API créé lors du démarrage rapide, ce fichier est openapi.yaml
.
Ajouter des définitions de sécurité
Ouvrez le fichier de configuration et ajoutez une nouvelle section securityDefinitions
. Dans cette section, ajoutez une nouvelle définition (auth0_jwt
) avec les champs suivants :
Champ | Description |
---|---|
authorizationUrl |
L’URL d’autorisation, doit être définie sur "https://{yourDomain}/authorize" |
flow |
Le flux utilisé par le schéma de sécurité OAuth2. Les valeurs valides sont "implicit" , "password" , "application" ou "accessCode" . |
type |
Le type du schéma de sécurité. Les valeurs valides sont "basic" , "apiKey" ou "oauth2" |
x-google-issuer |
L’émetteur d’un identifiant, doit être défini sur "https://{yourDomain}/" |
x-google-jwks_uri |
L’URI de la clé publique définie pour valider la signature JSON Web Token (JWT). Définissez ceci sur "https://{yourDomain}/.well-known/jwks.json" |
x-google-audiences |
L’identifiant de l’API, assurez-vous que cette valeur correspond à ce que vous avez défini dans Auth0 Dashboard pour l’API. |
securityDefinitions:
auth0_jwt:
authorizationUrl: "https://{yourDomain}/authorize"
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://{yourDomain}/"
x-google-jwks_uri: "https://{yourDomain}/.well-known/jwks.json"
x-google-audiences: "{yourApiIdentifier}"
Was this helpful?
Mettre à jour le point de terminaison
Maintenant, mettez à jour le point de terminaison en ajoutant un champ security
avec la section securityDefinition
que nous avons créée à l’étape précédente.
paths:
"/airportName":
get:
description: "Get the airport name for a given IATA code."
operationId: "airportName"
parameters:
-
name: iataCode
in: query
required: true
type: string
responses:
200:
description: "Success."
schema:
type: string
400:
description: "The IATA code is invalid or missing."
security:
- auth0_jwt: []
Was this helpful?
Dans l’exemple ci-dessus, le champ security
indique au proxy GCE que notre chemin /airportName
s’attend à être sécurisé avec la définition auth0-jwt
.
Après la mise à jour de la configuration OpenAPI, elle devrait ressembler à ceci :
---
swagger: "2.0"
info:
title: "Airport Codes"
description: "Get the name of an airport from its three-letter IATA code."
version: "1.0.0"
host: "{yourGceProject}.appspot.com"
schemes:
- "https"
paths:
"/airportName":
get:
description: "Get the airport name for a given IATA code."
operationId: "airportName"
parameters:
-
name: iataCode
in: query
required: true
type: string
responses:
200:
description: "Success."
schema:
type: string
400:
description: "The IATA code is invalid or missing."
security:
- auth0_jwt: []
securityDefinitions:
auth0_jwt:
authorizationUrl: "https://{yourDomain}/authorize"
flow: "implicit"
type: "oauth2"
x-google-issuer: "https://{yourDomain}/"
x-google-jwks_uri: "https://{yourDomain}/.well-known/jwks.json"
x-google-audiences: "{yourApiIdentifier}"
Was this helpful?
Redéployer l’API
Ensuite, redéployez votre API GCE pour appliquer les changements de configuration. Si vous avez suivi le Guide de démarrage rapide de Cloud Endpoints, vous pouvez redéployer l’API en saisissant les éléments suivants dans le Cloud Shell de Google :
cd endpoints-quickstart/scripts
./deploy_api.sh
Was this helpful?
Tester l’API
Une fois que vous avez redéployé l’API, appelez à nouveau l’API sans sécurité.
curl --request GET \
--url 'https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO'
Was this helpful?
var client = new RestClient("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.get("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'GET',
url: 'https://%7ByourGceProject%7D.appspot.com/airportName',
params: {iataCode: 'SFO'}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
conn.request("GET", "%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let request = NSMutableURLRequest(url: NSURL(string: "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Vous obtiendrez la réponse suivante :
{
"code": 16,
"message": "JWT validation failed: Missing or invalid credentials",
"details": [
{
"@type": "type.googleapis.com/google.rpc.DebugInfo",
"stackEntries": [],
"detail": "auth"
}
]
}
Was this helpful?
Et c’est exactement ce que l’on veut!
Accédez maintenant à la page Test de la définition de votre API Google Endpoints sur le Auth0 Dashboard et copiez le jeton d’accès sous la réponse :
Effectuez une demande GET
à votre API avec un en-tête d’autorisation du Bearer {ACCESS_TOKEN}
pour obtenir un accès autorisé :
curl --request GET \
--url 'https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO' \
--header 'authorization: Bearer {accessToken}'
Was this helpful?
var client = new RestClient("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO");
var request = new RestRequest(Method.GET);
request.AddHeader("authorization", "Bearer {accessToken}");
IRestResponse response = client.Execute(request);
Was this helpful?
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("authorization", "Bearer {accessToken}")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(res)
fmt.Println(string(body))
}
Was this helpful?
HttpResponse<String> response = Unirest.get("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
.header("authorization", "Bearer {accessToken}")
.asString();
Was this helpful?
var axios = require("axios").default;
var options = {
method: 'GET',
url: 'https://%7ByourGceProject%7D.appspot.com/airportName',
params: {iataCode: 'SFO'},
headers: {authorization: 'Bearer {accessToken}'}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});
Was this helpful?
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer {accessToken}" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"GET"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
Was this helpful?
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"authorization: Bearer {accessToken}"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Was this helpful?
import http.client
conn = http.client.HTTPSConnection("")
headers = { 'authorization': "Bearer {accessToken}" }
conn.request("GET", "%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO", headers=headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
Was this helpful?
require 'uri'
require 'net/http'
require 'openssl'
url = URI("https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(url)
request["authorization"] = 'Bearer {accessToken}'
response = http.request(request)
puts response.read_body
Was this helpful?
import Foundation
let headers = ["authorization": "Bearer {accessToken}"]
let request = NSMutableURLRequest(url: NSURL(string: "https://%7ByourGceProject%7D.appspot.com/airportName?iataCode=SFO")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
Was this helpful?
Et voilà!