aws-samples / aws-lex-web-ui

Sample Amazon Lex chat bot web interface
Other
744 stars 471 forks source link

No 'Access-Control-Allow-Origin' header is present on the requested resource. #93

Closed Lincoln23 closed 6 years ago

Lincoln23 commented 6 years ago

This is on an Ubuntu 16.04 server hosted on EC2. I am just using the defaults flowerBot

I am receiving the error Failed to load https://lex-web-ui-codebuilddeploy-19ewrp3tf-webappbucket-1qfovcoqzfewy.s3.amazonaws.com/lex-web-ui-loader-config.json: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://ip' is therefore not allowed access.

and

Error: error getting chatbot UI config from url: https://lex-web-ui-codebuilddeploy-19ewrp3tf-webappbucket-1qfovcoqzfewy.s3.amazonaws.com/./lex-web-ui-loader-config.json
    at XMLHttpRequest.r.onerror (config-loader.js:89).

I have tried adding this to my config file in etc/apache2/apache2.conf

<Directory /var/www/>
     Header set Access-Control-Allow-Origin "*"
</Directory>

then running sudo a2enmod headers

How would I solve this problem?

Follow up Reading This Guide I tried changing it to

 <Directory /var/www>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
    # Always set these headers.
  Header always set Access-Control-Allow-Origin "*"
  Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
  Header always set Access-Control-Max-Age "1000"
  Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, 
  authorization, accept, client-security-token"

  #Added a rewrite to respond with a 200 SUCCESS on every OPTIONS request.
  RewriteEngine On
  RewriteCond %{REQUEST_METHOD} OPTIONS
  RewriteRule ^(.*)$ $1 [R=200,L]
  </Directory> 

and doing sudo sudo a2enmod rewrite

I still get the same error but now I get an additional warning VM232:1 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://lex-web-ui-codebuilddeploy-19ewrp3tf-webappbucket-1qfovcoqzfewy.s3.amazonaws.com/lex-web-ui-loader-config.json with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.

bobpskier commented 6 years ago

This link might help with respect to cross origin configuration within the lex-web-ui. https://github.com/aws-samples/aws-lex-web-ui/tree/master/src#cross-origin-configuration. You'll need to configure the appropriate parentOrigin and iframeOrigin properties in the json configuration file.

Lincoln23 commented 6 years ago

@bobpskier I am a bit confused on how to do this, for

<script src="https://iframe-host.example.org/lex-web-ui-loader.js">
  </script>

I would point that to the lex-web-ui-loader.js link on s3 I have https://s3.amazonaws.com/ mybucket name /lex-web-ui-loader.js

for

  var loaderOpts = {
      baseUrl: 'https://iframe-host.example.org/'
    }

I am not sure how to get the baseUrl of my s3 is it https://s3.console.aws.amazon.com/s3/buckets/ name /?region=us-east-1&tab=overview ?

for

      ui: {
        // origin of the parent site where you are including the chatbot UI
        parentOrigin: 'https://mysite.example.org'
      },

I put my ip address

and for

      iframe: {
        // origin hosting the HTML file that will be embedded in the iframe
        iframeOrigin: 'https://iframe-host.example.org'
      }

I am not sure which file I should point that to on my s3

Here is the s3 bucket created, screenshot_3 Could you point me to which file I should link to for each field? Sorry I am very new to this, thanks for helping

bobpskier commented 6 years ago

A couple of options exist to set the configuration. When you first launch the CloudFormation stack for the aws-lex-web-ui, the WebAppParentOrigin can be configured as a parameter. This I believe sets the parentOrigin in the lex-web-ui-loader-config.json as well as the resulting iFrameOrigin. It would be easy to run through this again.

If you have an S3 bucket now containing the deployed lex-web-ui from your cloudformation stack, you can update the lex-web-ui-loader-config.json file in the S3 bucket. When you upload and overwrite this file, make sure the file is made publicly accessible. The config would look something like:

{ "cognito": { "poolId": "us-east-1:[YOUR POOL ID]" }, "lex": { "botName": "[YOUR BOT NAME]", "initialText": "Hello, [YOUR INITIAL TEXT].", "initialSpeechInstruction": "", "reInitSessionAttributesOnRestart": false, "botAlias": "[YOUR BOT ALIAS]" }, "ui": { "parentOrigin": "https://[YOUR PARENT ORIGIN]", "toolbarTitle": "[YOUR TITLE]", "toolbarLogo": "", "pushInitialTextOnRestart": false, "AllowSuperDangerousHTMLInMessage": true }, "polly": { "voiceId": "Salli" }, "recorder": { "preset": "speech_recognition" }, "iframe": { "iframeOrigin": "https://[STACK RESOURCE ID]-webappbucket-[YOURS3BUCKETNAME].s3.amazonaws.com", "iframeSrcPath": "/index.html#/?lexWebUiEmbed=true", "shouldLoadIframeMinimized": false } }

In your case, you'd probably only be initially changing parentOrigin and iframeOrigin.

parentOrigin would be configured based on the domain used by your Ubuntu web server running on EC2.

From your initial post I believe your iframeOrigin would currently be https://lex-web-ui-codebuilddeploy-19ewrp3tf-webappbucket-1qfovcoqzfewy.s3.amazonaws.com

Lincoln23 commented 6 years ago

@bobpskier Thanks, I got it to work! Which file on the S3 bucket would I have to change to switch the color of the ChatBot UI? Is it lex-web-ui.min.css in the s3 bucket? Thanks

Edit: it's all good, I managed to figure it out, Thanks for your help!

DavidJohnElson commented 5 years ago

I'm facing the same issue, tried to solve using the same link i.e., https://github.com/aws-samples/aws-lex-web-ui/tree/master/src#cross-origin-configuration still the issue is not solve screenshot 139 and for the same I can see another error too. I am very new to this. help me! Thanks in prior

bobpskier commented 5 years ago

@DavidJohnElson When deploying the lex-web-ui as an iframe in a web page, the parent origin needs to be specified when the stack is created. In your case it looks like the parent origin is http://localhost:63342. Do you recall if you specified a parent origin when you created the lex-web-ui CF stack? Eventually when the stack is complete, configuration in the lex-web-ui specifies the parent origin. Configuration in the s3 bucket where the lex-web-ui is deployed also defines the cors configuration. You could adjust these areas manually or you could delete and then redeploy the stack and specify the parent origin of http://localhost:63342. For a production web app this would be the origin where the app is really deployed.

To manually change the config you could download and edit a file from the S3 bucket with the name lex-web-ui-loader-config.json to set the parent origin to the correct value. You would then need to upload the changed file back to S3 allowing public read for the file. Next you'd want to look at the s3 bucket cors configuration to set the allowed origins including http://localhost:63342.

I tend to think it is easier to delete the stack for the lex-web-ui in your account and then rebuild the stack and specify the parent origin as well.

DavidJohnElson commented 5 years ago

I've created a New stack and added the http://localhost:8000 in WebAppParentOrigin and /lex in WebAppPath, and when i access http://localhost:8000/lex I've included the SnippetUrl in lex.html in this case mentioned as lex and the urls snippet-lex-web-ui-2 and Provided Public access to S3 bucket to the new stack created, still the page is empty, and if i view the error in console lex-web-ui-2 error and the JSON file config stact2

Abishek05 commented 5 years ago

Yes, I'm facing the same issue too. Has anyone solved the CORS problem? Looks like changing WebAppParentOrigin to localhost doesn't help. Maybe there's more to it?

bobpskier commented 5 years ago

@Abishek05 @DavidJohnElson

I went through the full process of deploying a new lex-web-ui stack and was able to embed the ui on a default vue js application running on http://localhost:8080. No CORS issue was observed.

The error above from @DavidJohnElson above indicates the js script loaded by the app on localhost:8000 could not load the lex-web-ui-loader-config.json file due to a CORS issue most likely due to configuration on the S3 bucket.

The CORS configuration is managed in two places. It needs to be properly set in both.

1) The S3 bucket holding the deployed lex-web-ui. The CF stack will create this bucket and will set the CORS configuration to the value specified in WebAppParentOrigin. You can view the CORS configuration in the AWS S3 console. Open the bucket created by running the lex-web-ui CF stack and click on the Permissions tab. Select CORS configuration. You should see the AllowedOrigin set to the WebAppParentOrigin parameter you provided in CF. In my test today it looks like:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>http://localhost:8080</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>

2) The lex-web-ui-loader-config.json contained in the S3 bucket and downloaded to the client.

The "ui" section contains the parentOrigin. In my test today it was set to:

 "ui": {
    "parentOrigin": "http://localhost:8080",
    "toolbarTitle": "Order Flowers",
    "toolbarLogo": "",
    "enableLogin": false,
    "AllowSuperDangerousHTMLInMessage": true,
    "shouldDisplayResponseCardTitle": true,
    "pushInitialTextOnRestart": false
  },

The parentOrigin in the configuration json file and the AllowedOrigin in the CORS configuration should match.

I suspect the S3 CORS configuration is most likely the problem for @DavidJohnElson.

If it would be helpful, I can record the full steps I used to test this out in a screen recording. Here is a summary:

1) Setup a new vue project from scratch using (You can get vue from https://vuejs.org)

vue init webpack vueapp01

2) cd into vueapp01 an run

npm run dev

This brings up an app running on http://localhost:8080. Test opening this url in chrome.

3) Launched a new CF stack for lex-web-ui in my AWS account and specified a parent origin of

http://localhost:8080

4) Waited for the stack to complete and opened the snippet URL and copied the required script elements.

5) Opened the index.html for the vue js app and pasted in the script elements. It now looks like the following:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>vueapp01</title>
  </head>
  <script src="https://lex-web-ui-localhost-codebuilddeploy-webappbucket-y1pzq6ndv445.s3.amazonaws.com/lex-web-ui-loader.min.js"></script>
  <script>
    var loaderOpts = {
      baseUrl: 'https://lex-web-ui-localhost-codebuilddeploy-webappbucket-y1pzq6ndv445.s3.amazonaws.com/'
    };
    var loader = new ChatBotUiLoader.IframeLoader(loaderOpts);
    loader.load()
      .catch(function (error) { console.error(error); });
  </script>

  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

6) Shut down the vue js app and rebuilt / restart the app by running

npm run dev

7) Refreshed the browser page pointed at http://localhost:8080. I've disabled caching for this test.

The CORS errors were not present after this setup.

DavidJohnElson commented 5 years ago

@bobpskier Thank you so much, It helped me. Just followed step by step and it's working fine now.