Azure WebApps でCORSの設定をしよう＆ お手軽SNS認証設定をしよう

こんにちは。まーやです。
Microsoft Azure の1サービスである WebApps、使ったことありますか？なんとなく使っているけれども使いこなせていないあなたに、うってつけな簡単機能設定についてまとめます。この記事では私自身が使ってみて便利だな～と思った次の2つの機能をご紹介します。

- SNS認証設定
- CORS設定

1つは知って超ベンリと感じた機能(SNS認証設定)、もう一つは実際に必要に迫られて調査・使用した機能(CORS設定)です。

# 解説に使うシステム
今回は「チャットルームシステムを構築する」という形で2つの機能の解説を進めていきたいと思います。本投稿でのシステムの流れは次のとおり。

- サーバに接続したとき(チャットルームにアクセスしたとき)にSNS認証が行われる
- 認証OK後チャットをスタートする
- チャットルームの過去情報取得APIをたたいて会話履歴が表示される

## システム構成
↑に書いたシステムをざっくり図化するとこんな感じ。Azure Webapps 2台で運営することにします。
![Untitled (1).png](https://qiita-image-store.s3.amazonaws.com/0/60850/e0b70034-f511-8b09-a4e4-e9db43859b0e.png)

Node使ってるんだから会話履歴もNodeからとればいいのでは・・・となりそうですが、その辺は共通基盤APIがあると想定して別のサーバへAPIを使って取りに行くということにしましょう。

チャットルームへのログインに使う認証処理も、自前でつくれるやん、と言われればその通りですが、SNS認証ならすでに認証基盤が各SNSに用意されているわけですから厄介な認証システムを作る手間を軽減することができます。それってシステム構築側としてはとてもハッピーなことだと思いませんか。

では、さっそくSNS認証の設定から見てみましょう。

# SNS認証設定
Azure WebAppsではサーバへの接続リクエストがあった時点でSNS認証システムを稼働させることが出来ます。自前のユーザIDとパスワードで認証しないとﾀﾞﾒ、というシステムでない限りは有効な認証システムとなりうるでしょう。


WebAppsのデフォルトでは次の5つ認証が用意されています(一部SNSではないですが、同様に設定して使うことが出来ます)。

- Facebook
- Google+
- Twitter
- (Microsoftアカウント)
- (Azure Active Directory)

社内向けシステムのログイン、とかであればAzure Active Directoryを使うのがよさそうですね。
が、今回はSNS認証機能として紹介しているので、試しにFacebookで認証できるようにしたいと思います。

### SNS認証を行うメリット
私が考える限りだと次のようなメリットを上げることが出来ます。

1. 認証システムの作成が不要になるので運用対象のコードがすっきり。運用対象の削減ができる
この認証設定機能を使うことで、そもそも自前の認証システムの作成がほぼいらなくなります(※1)。つまり運用対象の(しかもかなり重要な運用保守が必要となる）コードが削減できるわけですから、開発だけでなく運用面でもメリットがあるといえるでしょう。

1. 誰がどのSNSのアカウントで接続してきたかの情報がとれるので、マーケティング戦略も立てやすい（かもしれない) 
どのSNSのユーザ情報を使って認証したかという情報を得ることで、そのシステムの利用者の分布が見えやすくなります。そこからマーケティング的な知見や施策を見いだせるかもしれません。
e.g.)Twitterアカウントでログインしてる人が多いのでTwitterに広告を出してみよう、とか。

### WebAppsのSNS認証設定機能を使うメリット
「認証処理がほぼコードレスに！」です(※1)。
ダッシュボードから設定するだけで、SNS認証処理が発動しますので、この部分に関してはコードを書かなくてよくなります。とにかくお手軽に認証処理ができるわけです。
ただし、SNS側の利用設定は必要なのでご注意を(デベロッパーサイトのダッシュボードから設定するだけでOKなことが多いです)。

## 実際に設定してみる
では早速実際に設定してみましょう。
まず事前にSNS認証に使いたいSNSの開発者登録を行い、各種キーやアプリIDを取得します。
先ほど今回はFacebook認証をしてみる、とお話ししていましたので、Facebookのdeveloper登録をしてアプリID、アプリケーションシークレットを取得します。取得方法についてはネット上にあちこち落ちてますので、そちらを使って作成してみてください（[例えばこちらの記事など](http://qiita.com/ynunokawa/items/4c9147d2743d36e63832))。
ここではすでにFacebookアプリIDとシークレットキーが取得できたものとして進めます。

1. 認証をかけたいWebAppsサーバ(今回の場合はNode.js&html5/JSがのっているサーバ)を選択し、メニューから「認証/承認」を選択します。デフォルトではApp Service認証がオフになっていると思いますので、これをオンにします。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/60850/8cbb1601-c676-c448-225f-8ae733953446.png)
　
2. 認証できなかった場合の挙動の設定を選択します。ここには必ずこのアカウントがないと困る！というSNSアカウントを設定しておくといいと思います。SNS認証が出来なかった場合は別の認証をさせたい(例えば自前の認証システムを通ってもらうなど)場合は、要求の許可を選択しておけばよいと思います。そのあと、SNS認証させたい項目を選択します。今回の場合はFacebookです。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/60850/5cdc154e-6cf2-033e-c40a-efc00b875b41.png)

3. Facebook developerサイトで発行されたアプリIDとアプリケーションシークレットを設定し、Facebookからどんな情報を受け取るかを選択します。情報の取得範囲の説明はこのページに書いてありますので、慎重に選択しましょう。取得範囲設定は複数選択も可能です。設定したら一番下にあるOKボタンを押すのを忘れずに。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/60850/c96903fd-309c-da9b-8118-a2d34b49f0ba.png)

4. OKボタン押下後、↓のように「構成済み」と表示されたら保存ボタンを押してSNS認証処理作成完了。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/60850/7bc7d68f-2728-c89c-930b-9d6f0d6322fc.png)

5. 認証してみよう
ではサイトにアクセスしてみます
![A1.png](https://qiita-image-store.s3.amazonaws.com/0/60850/5d369025-23b7-8f2a-21ae-8433f30af563.png)
<img width="936" alt="スクリーンショット 2016-09-23 17.17.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/60850/385af1b2-7646-a7f6-7718-6bf9f2910e38.png">


できました。簡単ですね。

# CORS設定
## 私がCORSエラーに出会うまで
よし、認証もできた、中のチャットルームシステムもできた。実際に各サーバにデプロイして結合テストするぞ！
と意気込んでいざ実行してみたところ、過去情報取得APIをたたいたところ、情報が取れない。。。
何だろうと思ってログを確認してみると次のようなエラーログが。

```
XMLHttpRequest cannot load https://xxx.jp/xxxx.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'null' is therefore not allowed access.
```

ふむ。。。なんとも見覚えのあるエラー。。。
「CORS設定されていないときのエラー」です。

## CORSのおさらい
CORSとは「Cross-Origin Resource Sharing」の略でオリジン(そのシステムが動いているドメイン）以外のドメインからデータをとるときの仕組みを指します。アクセスコントロールの一つです。CORSを設定してあげることで、クロスオリジン(そのシステムが動いているドメイン以外のドメイン)のバックエンドからの呼び出しが可能になります。

今回出ているエラーは「データ取りに行ったけど、そのサーバは他のドメインからの接続を許可していなかったよ」というエラーがでているのです。

ではどうなっていれば接続許可され、データが取れるのでしょうか。
HTTPレスポンスヘッダに`Access-Control-Allow-Origin： https://xxx.jp`とでていれば `https://xxx.jp` から対象サーバへの接続が許可されている、ということになります。

## いざCORSの設定へ
これを修正するためには、Javascript側でもにゅもにゅする対応策もあるようですが、今回はデータ取得先であるAPIサーバも自分で作っているものなので、やっぱりサーバ側で対処するのが美しい。

しかしながらWebAppsはPaaSシステムですから、基本的にはサーバにCLI接続してごりごり設定を書き換える・・・なんてことはできません。
CORSの設定もWebAppsデフォルトでは何も設定されていない状態です。
「WebAppsの場合はどうやってCORSの修正するのかしらん？」
「HTTPレスポンスヘッダに `Access-Control-Allow-Origin： https://xxx.jp` どうやっていれるのかしらん？」
と調べてみたところ、しれっとダッシュボードの中にあることがあっさり判明しました。

### WebApps CORS設定手順
1. 対象のWebApps(今回はJavaがのっている方のWebApps)を選択し、メニュー下の方にある「CORS」をクリックします。
2. 許可するドメインを設定する欄が出現しますので、対象となるドメインの設定を行います。この設定ではワイルドカードの利用も可能です。「世界中どこからでも接続OK!」というのであれば、*と設定してあげればよいです(あまり良いとは言えない設定ではありますが)。
3. 保存ボタンを押して設定完了。
![CORS.png](https://qiita-image-store.s3.amazonaws.com/0/60850/475fe812-68d8-25b3-f5dc-814fd3f3ed71.png)

保存ボタンを押下した後はすぐに反映作業に入ってくれます。ダッシュボード上右上の方に完了通知が来たら利用できます。


# まとめ

- WebAppsの認証機能を使うと認証システム作成が簡単
- CORS設定もダッシュボードからできるよ

Azureってダッシュボードでできることが多くて最初はてんやわんやするんですが、慣れるといろいろできるのが逆にいいかんじです。


------------------------------------
※1 SNS認証後その情報を使って何か処理が必要だったり、他の認証システムと組み合わせたりする場合も考えられるので「ほぼ」としました。ただただ認証ができればOK、のようなライトなシステムであればWebAppsのSNS認証設定機能を設定するだけで全然OKです。