vzurd
vzurd

Reputation: 1526

API Gateway not returning Response

I was trying GCP API Gateway using firebase authentication. I can see my request has been processed from the logs and completed with response code 200. However, I am not getting the response back to my client. I am getting the response when I call the function directly. Am I missing something ?

API Config

swagger: "2.0"
info:
  title: API Endpoints
  description: API Endpoints
  version: 1.0.1
schemes:
  - https
produces:
  - application/json
securityDefinitions:
  firebase:
    authorizationUrl: ""
    flow: "implicit"
    type: "oauth2"
    x-google-issuer: "https://securetoken.google.com/my-project"
    x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
    x-google-audiences: "my-project"
paths:
  /hello:
    get:
      summary: Test link
      operationId: hello
      x-google-backend:
        address: https://us-central1-my-project.cloudfunctions.net/hello
      security:
        - firebase: []
      responses:
        "200":
          description: A successful response
          schema:
            type: string
        "403":
          description: Failed to authenticate

Function

 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!';
  res.status(200).send(message);
};

Logs

Logs

Additional Query Initially, I had my functions private and was getting 403. It gave me 200 once I added allUsers with Cloud Functions Invoker to the permissions to the function I am trying to invoke. So I am a bit confused here. Part of the reason I am using API gateway with firebase auth is to protect it against unauthorised calls. And for firebase auth to work, I had to add allUsers, making it public. My understanding was that the API gateway alone would be public while all the backend services that it invokes would be private. In this case, the function can be directly invoked by anyone, rendering API Gateway useless. How can I setup the backend to private and only respond to authenticated calls through API gateway ?

Additional Logs

{
 insertId: "8c13b49c-2752-4216-8188-d445f4724ef14850908905639612439@a1"  
 jsonPayload: {
  api_key_state: "NOT CHECKED"   
  api_method: "1.myapi.GenerateRTCToken"   
  api_name: "1.myapi"   
  api_version: "1.0.1"   
  client_ip: "999.999.999.999"   
  http_method: "GET"   
  http_response_code: 200   
  location: "us-central1"   
  log_message: "1.myapi.GenerateRTCToken is called"   
  producer_project_id: "myproject"   
  request_latency_in_ms: 161   
  request_size_in_bytes: 4020   
  response_size_in_bytes: 579   
  service_agent: "ESPv2/2.17.0"   
  service_config_id: "myapi-config"   
  timestamp: 1606313914.9804168   
  url: "/generateRTCToken"   
 }
 logName: "projects/myproject/logs/myapi%2Fendpoints_log"  
 receiveTimestamp: "2020-11-25T14:18:36.521292489Z"  
 resource: {
  labels: {
   location: "us-central1"    
   method: "1.myapi.GenerateRTCToken"    
   project_id: "myproject"    
   service: "myapi"    
   version: "1.0.1"    
  }
  type: "api"   
 }
 severity: "INFO"  
 timestamp: "2020-11-25T14:18:34.980416865Z"  
}

Upvotes: 4

Views: 1638

Answers (3)

Jonathan Morales
Jonathan Morales

Reputation: 11

I have an similar issue with API Gateway throwing the same response validating a token against keycloak.

The issue was with the JWT, it was too long, we remove unused roles from the user and work perfectly.

Hope it helps.

Upvotes: 1

Soni Sol
Soni Sol

Reputation: 2612

To call the Google Cloud Function from the Api-Gateway without making it public you can grant the service account used by the API-Gateway the role CloudFunctions Invoker

On Creating an API config (4) : you set a service Account, take note of this service account.

Once you have identified the service account you can grant it the Cloud Funtions Invoker role to the service account. For these you can follow these steps:

  • Go to IAM&Admin
  • Look for the service account, and click on the pencil next to it( If you don't see the service account click on Add and type the service account email)
  • For role Select Cloud Functions Invoker
  • Click on Save

This will grant the service account the permission to call the functions without having them public.

Upvotes: 3

Harif Velarde
Harif Velarde

Reputation: 753

Take a look at this document where it is explained in detail how to use Firebase to authenticate in API Gateway.

In general there are two conditions that we need to keep on mind in order to configure these services:

When your client application sends an HTTP request, the authorization header in the request must contain the following JWT claims:

  • iss (issuer)
  • sub (subject)
  • aud (audience)
  • iat (issued at)
  • exp (expiration time)

To support Firebase authentication, add the following to the security definition in your API config:

securityDefinitions:
    firebase:
      authorizationUrl: ""
      flow: "implicit"
      type: "oauth2"
      # Replace YOUR-PROJECT-ID with your project ID
      x-google-issuer: "https://securetoken.google.com/YOUR-PROJECT-ID"
      x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/metadata/x509/[email protected]"
      x-google-audiences: "YOUR-PROJECT-ID"

Upvotes: 0

Related Questions