Can't get cookies in Apigee or see them on Trace, help!

may
Bronze 5
Bronze 5

Hi,

I need some help with capturing Set-Cookies, please.

So, one route sends three Set-Cookies back from the endpoint. I'm supposed to capture these cookies and manipulate them (add them to the response body).

However, I'm only able to capture the JSESSIONID cookie, and no other. I can't see the other cookies on Trace, but they all appear on Postman.

I've tried addind the property to target configuration:

<Property name="response.retain.headers">Set-Cookie</Property>.
 
I've tried capturing these cookies with (from reading other solutions here on the community):

 

  • context.getVariable('response.header.set-cookie.values') + '';
var a = hdr.substring(1, hdr.length - 1).split(',');
  • context.getVariable('response.header.set-cookie.values.string');
  • context.getVariable("message.header.Set-Cookie");
  • context.targetResponse.headers['Set-Cookie'][1];
  •  with ExtractVariables policy.
It either only get the JSESSIONID cookie or appears as undefined or null.
In another situation, when it was just one cookie, I did it with ExtractVariables and had no problems.
 
The three cookies being shown on Postman after the request through Apigee:
setCookie_postman.png
 
Can't find them on Trace (maybe I'm not looking right...?). I'm also getting a 'Location' header on Trace that I don't know where it is from, but not sure if it is related:
setcookie_trace.png

The cookies are set to different domains, could this be an issue? I can only get the first cookie, but I need the others.

setCookie_cookies.png

Any help is greatly appreciated!!

Thanks in advance.

Solved Solved
0 4 1,129
1 ACCEPTED SOLUTION

This should work:

context.getVariable('response.header.set-cookie.values.string');

I've never had a problem accessing the headers from an upstream system, even headers named "set-cookie".

Can't find them on Trace (maybe I'm not looking right...?).

If you cannot see them in Apigee Trace/Debug, then that means those headers are not being sent back by that upstream system. Surprise! But how can this be? You can clearly see them in Postman.

I'm also getting a 'Location' header on Trace that I don't know where it is from, but not sure if it is related...

Yes, I think this header is related! I'll bet you don't see the Location header in the Postman client, eh?

A Location header tells the browser to look in a different location for the information it is requesting. So I guess this is what is happening:

  1. the browser (or postman) sends a request into an endpoint managed by Apigee
  2. Apigee "proxies" it to the upstream system
  3. The upstream system responds with a 301 or 302 (or other 3xx stattus), along with the Location header that you observed.
  4. The browser (or postman) automatically "follows" that Location header and sends another request directly out to THAT endpoint. Apigee is not involved here.
  5. that endpoint does what it does, and sends back a response with some Set-Cookie headers.
  6. The browser or postman adds those cookies to the cookie store.

The Apigee API proxy is not involved in the 2nd request. That is why you don't see any Set-Cookie headers in the Apigee trace. It will not help  to use response.retain.headers .  

If you really want Apigee to intercept the response to the 2nd request, then you need to rewrite the Location header in the response to the 1st request, before sending it to the client. You need to change out the hostname, and replace it with the DNS name for your Apigee API endpoint. You can do that with some JavaScript. 

// attach this in the response flow
var loc = context.getVariable('response.header.Location');
if (loc) {
  loc = loc.replace('vtexid.vtex.com.br', 'my-apigee-endpoint-hostname');
  context.setVariable('response.header.Location', loc);
}

And then you may need to configure a 2nd proxy to handle inbound requests with a basepath of /VtexIdAuthSiteKnockout , which is the basepath of the URL in the Location header...this is the thing the browser will follow for the 2nd request.  and that proxy must have those inbound requests and proxy them to the actual endpoint, which is vtexid.vtex.com.br . On the response flow, you can use

context.getVariable('response.header.set-cookie.values.string');

...to get the set-cookie headers and do whatever you like to them. 

View solution in original post

4 REPLIES 4

This should work:

context.getVariable('response.header.set-cookie.values.string');

I've never had a problem accessing the headers from an upstream system, even headers named "set-cookie".

Can't find them on Trace (maybe I'm not looking right...?).

If you cannot see them in Apigee Trace/Debug, then that means those headers are not being sent back by that upstream system. Surprise! But how can this be? You can clearly see them in Postman.

I'm also getting a 'Location' header on Trace that I don't know where it is from, but not sure if it is related...

Yes, I think this header is related! I'll bet you don't see the Location header in the Postman client, eh?

A Location header tells the browser to look in a different location for the information it is requesting. So I guess this is what is happening:

  1. the browser (or postman) sends a request into an endpoint managed by Apigee
  2. Apigee "proxies" it to the upstream system
  3. The upstream system responds with a 301 or 302 (or other 3xx stattus), along with the Location header that you observed.
  4. The browser (or postman) automatically "follows" that Location header and sends another request directly out to THAT endpoint. Apigee is not involved here.
  5. that endpoint does what it does, and sends back a response with some Set-Cookie headers.
  6. The browser or postman adds those cookies to the cookie store.

The Apigee API proxy is not involved in the 2nd request. That is why you don't see any Set-Cookie headers in the Apigee trace. It will not help  to use response.retain.headers .  

If you really want Apigee to intercept the response to the 2nd request, then you need to rewrite the Location header in the response to the 1st request, before sending it to the client. You need to change out the hostname, and replace it with the DNS name for your Apigee API endpoint. You can do that with some JavaScript. 

// attach this in the response flow
var loc = context.getVariable('response.header.Location');
if (loc) {
  loc = loc.replace('vtexid.vtex.com.br', 'my-apigee-endpoint-hostname');
  context.setVariable('response.header.Location', loc);
}

And then you may need to configure a 2nd proxy to handle inbound requests with a basepath of /VtexIdAuthSiteKnockout , which is the basepath of the URL in the Location header...this is the thing the browser will follow for the 2nd request.  and that proxy must have those inbound requests and proxy them to the actual endpoint, which is vtexid.vtex.com.br . On the response flow, you can use

context.getVariable('response.header.set-cookie.values.string');

...to get the set-cookie headers and do whatever you like to them. 

Fantastic, thank you so much. I had all the pieces, but couldn't put the puzzle together.

Do you think I could achieve this with ServiceCallout policy to do the request instead of creating a second proxy?

I can’t envision a way to use ServiceCallout to solve the problem. The key point is, the user agent (browser or postman) will “follow the redirect”.  It will definitely make a new request to the URL specified in the Location header. What you want to do is insert Apigee into the middle of that second request. So I think you need a new proxyendpoint to make that happen. (It can be part of the same proxy bundle) 

It's clear now. I tested with the ServiceCallout, now I see what you're saying and why it wouldn't work like that. I talked to the endpoint's developer so we can reach a solution.

Thank you so much for your help ♥