サーバ気象予報
概要
とある会社に勤めている、K君はサーバのお天気管理システムを開発しています。しかし、気温と湿度の情報を取得・送信することができません。原因を究明して取得・送信出来るようにして下さい。
前提条件
client
の/etc/hosts
を変更しない
初期状態
prob4-proxy
からwebとapiにリバースプロキシをしている。- VNCのFirefoxから
http://web.test
にアクセスし、気温と湿度を取得・送信しようとするが送信できない。 - apiサーバの
/srv/api/
以下にexpressサーバの設定が記述されている。これらはnpm start
で起動できる。
終了状態
- VNCのFirefoxから
http://web.test
にアクセスし気温と湿度を取得・送信ができ、リソースが更新される。 prob4-api
のOSを再起動してもexpressサーバが自動で起動されているようになっている。
解説
この問題ではAPIサーバから取得する情報にCORS設定に問題があったためにブラウザ側でブロックされるのが原因でした。Proxyサーバに適切なCORSヘッダーを追加する設定を追加することで、正しくAPIサーバからリソースを取得することができる様になります。
CORS(Cross-Origin Resource Sharing)とは
自分とは異なるオリジンにリソースをリクエストするときにオリジン間リクエストが発生する。
セキュリティ上の都合のためブラウザはスクリプトから発生するオリジン間リクエストを制限しています。
同じオリジンからのリソース取得だけでは不便なので、異なるオリジンからWebサイトに対してのアクセスを可能をする仕組みがCORS設定です。今回はこの設定が間違っていました。
参考
オリジン間リソース共有 (CORS) – HTTP | MDN – Mozilla
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS
Origin (オリジン) – MDN Web Docs 用語集
https://developer.mozilla.org/ja/docs/Glossary/Origin
解法
工程①
APIにてexpressサーバを起動する
cd /srv/api
npm start
> [email protected] start /srv/api
> node server.js
server is listening on port 3000...
VNCに接続する。
web.test
にアクセスし取得・送信ボタンを行うがリソースが取得・送信できないことが確認できる。
デベロッパーツールで通信を確認してみるとCORS Missing Allow Originと表示されるのでCORSが原因ということが分かる
OPTIONの方をクリックし、ヘッダーを比較すると以下のようなことが確認でき、一部の設定に間違いがあることが分かる。
問題文にProxyサーバとあることからProxyサーバでヘッダーを書き換えていると予想できる。
確認してみると、間違えていることが分かるのでviなどで正しく修正し、Nginxを再起動する。
sudo vim /etc/nginx/nginx.conf
~~~~省略~~~~~~
server {
listen 80;
server_name api.test;
location / {
proxy_pass http://192.168.4.102:3000;
add_header Access-Control-Allow-Origin '*';
# POST を追加
add_header Access-Control-Allow-Methods 'GET, POST';
# Acccept から content-type に変更
add_header Access-Control-Allow-Headers 'content-type';
}
}
sudo systemctl restart nginx
web.test
よりリソースが送信・取得できる。
工程②
prob4-api
のOSを再起動してもexpressサーバが自動で起動されているようになっている。とあるのでこれを行う。
viなどでサービスファイルを作成し自動起動を有効化することで終了条件を満たせる。なお別解としてcronなどでも起動できました。
sudo vim /etc/systemd/system/api.service
[Unit]
Description=express server
After=syslog.target network.target
[Service]
Type=simple
ExecStart=/usr/bin/node /srv/api/server.js
WorkingDirectory=/srv/api
KillMode=process
Restart=always
User=user
Group=user
[Install]
sudo systemctl enable weather
その他
チームによってはヘッダーが二重についていることがあったが、終了条件を満たせていれば満点にしました。