amazon-web-servicesamazon-s3facebook-canvas

How to configure AWS S3 to allow POST to work like GET


Facebook states in their canvas setup documentation:

Our servers will make an HTTP POST request to this web address. The retrieved result will be displayed within the Canvas frame on Facebook.

My application is hosted on AWS S3 as a static website using the following CORS configuration:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>HEAD</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Already I'm having an issue here. GET requests work perfectly, but POSTing to http://my-bucket-name.s3-website-us-east-1.amazonaws.com kicks back:

<html>
    <head>
        <title>405 Method Not Allowed</title>
    </head>
    <body>
        <h1>405 Method Not Allowed</h1>
        <ul>
            <li>Code: MethodNotAllowed</li>
            <li>Message: The specified method is not allowed against this resource.</li>
            <li>Method: POST</li>
            <li>ResourceType: OBJECT</li>
            <li>RequestId: 94159551A72424C7</li>
            <li>HostId: +Lcz+XaAzL97Y47OZFvaTwqz4Z7r5koaJGHjZJBBMOTUHyThTfKbZG6IxJtYEbtsXWcb/bFxeI8=</li>
        </ul>
        <hr/>
    </body>
</html>

Step 1: ^ I think I need to get this this working.

but wait, there's more

Facebook also requires a secure url. so for this, I went to cloudfront.

My configuration looks like this:

Cloudfront Configuration

More Cloudfront Configuration

Just like when working with S3 directly, making GET requests to https://app-cloudfront-id.cloudfront.net/ works like a champ, POSTing, kicks back this:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>MethodNotAllowed</Code>
    <Message>The specified method is not allowed against this resource.</Message>
    <Method>POST</Method>
    <ResourceType>OBJECT</ResourceType>
    <RequestId>657E87A80AFBB3B0</RequestId>
    <HostId>SY2g4smvhr06kAAQYVMsYeQZ+pSKbIIvsh/OaPBiMADGt5UKut0sXSZkFsnFmcRXQ2PFBVgPK4M=</HostId>
</Error>

Viewing the app on facebook.com shows:

app on facebook

Am I missing something?


Solution

  • so - I too thought this should be easy and well supported by AWS in 2016. Apparently, from all the reading I've done, we're wrong.

    There's no way to serve the index page for a facebook app from s3 - with or without cloudfront.

    It might be possible to serve the index page from an alternate origin (ie, your own httpd running somewhere) through cloudfront and everything else from s3 - but I haven't tried to dig into that rabbit hole. And if you're still having to run your own HA httpd...the complexity might not be worth it depending on your asset scale. ie http://www.bucketexplorer.com/documentation/cloudfront--how-to-create-distributions-post-distribution-with-multiple-origin-servers.html

    you -can- use cloudfront in front of your own origin httpd serving the static content to take advantage of the cache and edge distribution - it will just forward the POST (and PUT etc) to your origin and bypass the cache edge.

    these answers are old, circa 2011, - but I can't find any evidence that anything has changed with this.

    https://forums.aws.amazon.com/thread.jspa?messageID=228988&#228988

    https://forums.aws.amazon.com/thread.jspa?threadID=62525

    Hopefully we can get some activity on this thread to prove me wrong, I could use this right now too.