New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flask Redirect on AWS Requires Javascript Browser #303

Closed
mcrowson opened this Issue Sep 5, 2016 · 12 comments

Comments

Projects
None yet
2 participants
@mcrowson
Collaborator

mcrowson commented Sep 5, 2016

When making a POST to flask-restless, a flask redirect is returned to GET the new resource. When running Flask locally on both Chrome and Postman (no JS), the GET resource is correctly returned. On AWS, the POST request returns the raw HTML of the redirect.

http://pastebin.com/N9pcr7nZ

@mcrowson

This comment has been minimized.

Collaborator

mcrowson commented Sep 6, 2016

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 6, 2016

There is a reason for this: there is (was??) no way to set a cookie on a redirect through the API gateway. This meant that some login forms that returned a cookie and a redirect - like the Django admin login - did not work. The 200 + redirect HTML is a hack: https://github.com/Miserlou/Zappa/blob/master/zappa/middleware.py#L129

The question is, what do we do here? There are a few options:

  • Check to see if this hack is still necessary. It's possible that API Gateway is now capable of setting cookies upon redirects.
  • Add the ability to disable this feature. This is probably a sensible feature for people running APIs who don't want this, but it adds a configuration complexity that I'm not crazy about.
  • Warn in documentation and expect the change in the application layer.

Thoughts?

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 6, 2016

Related:

https://forums.aws.amazon.com/thread.jspa?threadID=216264
http://stackoverflow.com/questions/35595672/aws-api-gateway-use-302-redirect-and-set-cookie-header

It also looks like we could choose to do this only when there is a Set-Cookie, although because of a separate hack for multiple cookies, that's usually the case.

@mcrowson

This comment has been minimized.

Collaborator

mcrowson commented Sep 6, 2016

Something else to consider is that these POST requests that originally got me started looking at this is returning a 201 response.

Edit: This 201 shouldn't cause any redirects, but be sent directly to client.

@mcrowson

This comment has been minimized.

Collaborator

mcrowson commented Sep 6, 2016

Recent blog post on the topic: https://aws.amazon.com/blogs/compute/redirection-in-a-serverless-api-with-aws-lambda-and-amazon-api-gateway/

It looks like they suggest raising errors for non 2xx responses and handling each raised error separately (302 differs from 404 for example).

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 6, 2016

Gah, I thought I was getting closer on this today, but I'm not sure. I still maintain that this is a defect in Lambda Python.

There are two ways to return data from Lambda to the API Gateway: returning a response dictionary, or raising an exception.

The response dictionary is great, we can map our headers to the response okay, no problems. This is how we do the 200 responses. The exception is different, however - we can only pass a string. So, we make an OrderedDict, jsonify and encode it then decode and map it in the template. I think, or at least at the time it was written orginally, this can only be done for body of the response, not for the headers.

If this isn't the case, maybe we could do something like:

response_parameters["method.response.header.Set-Cookie"] = "#set($_cookie = $util.parseJson($input.path('$.errorMessage'))['Set-Cookie'])\n$util.base64Decode($_cookie)

I have no idea if this will work or not. I doubt it.

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 6, 2016

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 19, 2016

I actually had a dream about this last night and woke up thinking that maybe we could have a different template in place for when the content type contains "application/", that way we can still set cookies and inject redirect HTML for normal HTML, but skip it for API responses that probably don't need to set cookies anyway. Does that make sense? Is that even possible..

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 22, 2016

Okay, I have published a partial, dream-inspired fix. It will now only inject the redirect HTML for the text/html content type. The response code is still wrong, but I think it should now be possible to set up API gateway to use the correct status code for application/json (and similar) redirects (assuming we never set cookies on API responses), if anybody wants to take a stab at it.

@mcrowson

This comment has been minimized.

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Sep 27, 2016

Okay, I think this should be super-possible now!

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html

@mgalvey Did a non-Zappa test, confirmed to work with this: http://codepad.org/VjonHIiS (sans multiple headers)

The only challenge is now is going to be figuring out what the right magic spell is to make boto recognize the new proxy stuff.

@Miserlou

This comment has been minimized.

Owner

Miserlou commented Oct 11, 2016

@Miserlou Miserlou closed this Oct 11, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment