4

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/securetoken@system.gserviceaccount.com"
    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"  
}
vzurd
  • 1,416
  • 2
  • 15
  • 37
  • did you try to follow the official documentation? https://cloud.google.com/api-gateway/docs/quickstart-console – Harif Velarde Nov 04 '20 at 22:10
  • Yes. I am not using API key as mentioned in the documentation. Instead I am using firebase auth. It really doesn't tell me why I wouldn't recieved a response nor it does answer my second question. – vzurd Nov 05 '20 at 02:59
  • What do you mean by "not getting any response back"? Does it hang? For how long? Any eventual error? – Philip Wigg Nov 18 '20 at 18:50
  • Yes it waits for the response and times out eventually. – vzurd Nov 20 '20 at 03:11
  • I see this as possibly two issues mixed: one being not getting an answer at all, and the other one might be something with permissions within the project( this is why you needed to make the functions public). Are the functions deployed from the GCP project or from the firebase project? – Soni Sol Nov 24 '20 at 20:34
  • about not getting a response at all, 1) could you share the api-gateway logs? 2) when calling the cloud function directly do you get any response? – Soni Sol Nov 24 '20 at 23:49
  • 1. `2020-11-25 00:53:59.184 EST us-central1 200 1.2 s 1.quadlii_api_1vss1kcaz7bkf_apigateway_fan_demand_cloud_goog.GenerateRTCToken is called` Log from API Gateway suggests the response was returned. Response Code was 200 2. Yes The function is public. I still havenet figured out how to make it private and still invoke it for authenticated users. See my `Additional Query` in the question – vzurd Nov 25 '20 at 08:21
  • I posted an answer for the functions needing to be public, If you need firther help with the functions not having an answer you can pubish a new question or share the full logs so we have more debugging info to help you. – Soni Sol Nov 26 '20 at 00:38
  • I have added the logs as well. I couldn't find anything from the logs other than the fact that it return 200. Is the gateway interfering with the proxy to send the response back to the sender ? – vzurd Nov 26 '20 at 14:48
  • @SoniSol can you please check the logs and let me know if more info? – vzurd Nov 30 '20 at 16:51

3 Answers3

3

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.

Soni Sol
  • 2,367
  • 3
  • 12
  • 23
1

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.

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 20 '22 at 14:09
0

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/securetoken@system.gserviceaccount.com"
      x-google-audiences: "YOUR-PROJECT-ID"
Harif Velarde
  • 733
  • 5
  • 10
  • Sorry it doesn't answer my question. I am able to authenticate and trigger the function or service. But I am not receiving any response back. – vzurd Nov 13 '20 at 10:58