Error: No 'Access-Control-Allow-Origin' when make Facebook instant games

## Vấn đề

Reactjs app được viết cho nền tảng [facebook instant games](https://developers.facebook.com/docs/games/instant-games) và được host bởi [Facebook content hosting](https://developers.facebook.com/docs/games/services/contenthosting/)

Vấn đề là khi app gọi api thì bị lỗi: Error: No 'Access-Control-Allow-Origin' vì vấn đề Cross-Origin Resource Sharing (CORS)

Mô hình ứng dụng như sau:
Client -> Reactjs app (hosted on facebook domain) -> call api.mydomain.com -> CORS Error.

## Giải quyết
ban đầu vì không hiểu rõ CORS nên đã tưởng phải config ở hosted domain (facebook) nhưng bắt gặp trả lời này trên [stackoverflow](https://stackoverflow.com/questions/46681719/facebook-webgl-game-facebook-simple-hosting-cors-possible)

```
CORS is the solution to your problem here.

This question/the answer is not Facebook specific - the issue would be the same 
with any other domain serving your content, that is different from your own.

Your client-side code is hosted under the Facebook domain, and tries to make 
a request to your domain - that is the cross-domain part. Your domain is the
party that holds the power to either allow or deny this request - by default,
it would be denied, but by responding with the appropriate header,
your server can signal to the browser, "yes, that's ok, he [your code running
under facebook.com] is one of the good guys ..."

So you need to configure this on your server, that you want to make the request to.
```

Tức là mình cần config ở API server của mình là được rồi. yeah.

## Config nginx to support CORS

- file:/etc/nginx/nginx.conf

```
    ...
    server {
        listen 443;
	server_name api.domain.com;
        
	ssl on;
	ssl_certificate /root/ssl/ssl-bundle.crt;
        ssl_certificate_key /root/ssl/private.key;

        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://unix:/root/app/api/app.sock;

	    include /etc/nginx/conf.d/allow-cors.conf;
        }

        location /.well-known/ {
            root /root/ikuze/.ssl;
        }
    }
    ...

```

- file: /etc/nginx/conf.d/allow-cors.conf

```
if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' '*';
    #
    # Om nom nom cookies
    #
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    #
    # Custom headers and headers various browsers **should** be OK with but aren't
    #
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
    #
    # Tell client that this pre-flight info is valid for 20 days
    #
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
}

if ($request_method = 'POST') {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
 
if ($request_method = 'GET') {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
```

```
$ nginx -s reload
```

## Done!