JavaScript超初心者向け Meteor メモ (5) ログイン画面を作る （Google/Twitterアカウント編）

# JavaScript超初心者向け Meteor メモ (5) ログイン画面を作る  （Google/Twitterアカウント編）

[Meteor.js](https://www.meteor.com/)は、 **Webアプリづくりを楽しくする** フレームワークです。

<a href="https://www.meteor.com/"><img src="http://img.dfm.lrv.jp/meteor1/meteorlogo.jpg"></a>

# 今回はTwitterとGoogleのアカウントを使ってログインしてみます。

[前回](http://qiita.com/tadfmac/items/714654958c127c053d51)は、`accounts-ui`と`accounjts-password`を利用して、メールアドレスとパスワードでログインするログイン画面を作ってみました。

今回は、SNSアカウントを使ってログインするログイン画面を作ってみたいと思います。
よく、![sign in with twitter](http://img.dfm.lrv.jp/meteor5/sign-in-with-twitter-gray.png)みたいなボタンで実装されてるアレですね！

さて、MeteorではTwitterなどのアカウントを使ったログイン機能は簡単に実装できます。

具体的には、MeteorのAPI、[Meteor.loginWith<サービス名>](http://docs.meteor.com/#meteor_loginwithexternalservice)で提供されます。
現在、下記のようなサービスに対応しているようです。

- Meteor.loginWithMeteorDeveloperAccount
- Meteor.loginWithFacebook
- Meteor.loginWithGithub
- Meteor.loginWithGoogle
- Meteor.loginWithMeetup
- Meteor.loginWithTwitter
- Meteor.loginWithWeibo

今回は、GoogleとTwitterで試してみようと思います。
（私がアカウントを持ってて、すぐ使えるのそれだけだったので。）

## 準備。GoogleとTwitterのアカウントを作成しておく

GoogleとTwitterのアカウントをお持ちでない場合、アカウントを作っておいてください。

- [Google](https://google.com/)
- [Twitter](https://twitter.com/)

作り方は、下記サイトを見ればわかります。

- [Google アカウントを作成する](https://support.google.com/accounts/answer/27441?hl=ja)
- [Twitterに登録する方法](https://support.twitter.com/groups/50-welcome-to-twitter/topics/204-the-basics/articles/230266-twitter)

## まずはドキュメント（docs.meteor.com）を読んでやり方を教えてもらう。

[ドキュメント](http://docs.meteor.com/#meteor_loginwithexternalservice)を読むと、

> External login services typically require registering and configuring your application before use. 
> The easiest way to do this is with the accounts-ui package which presents a step-by-step guide to configuring each service. 

とあります。

つまり、「外部サービスでログインするには、アプリを使う前に登録が必要だが、`accounts-ui`を使うのが一番簡単！」ということのようです。

本当にそんなに簡単なの？
というわけで、もちろん、一番簡単な方法でやってみたいと思います。

## やってみよう！

それでは、はじめます！

### プロジェクトを作ってアドオン追加

いつも通り、最初にプロジェクト作成とアドオンの追加を行います。

今回は、Googleとtwitterを使いますので、`accounts-google`と`accounts-twitter`を追加します。
あと、`accounts-ui`も登録しておきましょう。

```
> meteor create twtest
> cd twtest
> meteor add accounts-google accounts-twitter accounts-ui
```

これでOKです。

### htmlを書き換える

プロジェクトは、`meteor create`コマンドで作成したので、サイトの内容は「hello world」そのままです。
`accounts-ui`を利用するために、`twtest.html`を編集します。

[前回](http://qiita.com/tadfmac/items/714654958c127c053d51)も出てきましたが、`accounts-ui`はログイン画面を追加するアドオンです。これを呼び出すために、htmlへ`{{> loginButtons}}`を埋め込みます。


```twtest.html
<head>
  <title>twtest</title>
</head>

<body>
<div>{{> loginButtons}}</div>
  {{> hello}}
</body>

<template name="hello">
  <h1>Hello World!</h1>
  {{greeting}}
  <input type="button" value="Click" />
</template>
```

追加は1行だけです。

それでは、`http://localhost:3000`にブラウザでアクセスしてみましょう。

![最初の画面](http://img.dfm.lrv.jp/meteor5/ss1.png)

こんな風に表示されたら、とりあえずOKです。

### 「accounts-uiの言う通りに」設定する

ここから先のやり方は、こと細かく`accounts-ui`が教えてくれます。
どういうこと？
やってみれば判ります！w

#### まずは、Googleアカウントからです。

Meteorの設定と、Googleへのアプリケーションの登録を同時に行います。

1. 先ほど動かした、http://localhost:3000 で「Sigin in」をクリック
2. メニューが表示されるので、「Configure Google Login」をクリック
3. さらにポップアップが出てくるので、あとは **書いてある通りに** やる。
![Google設定手順1](http://img.dfm.lrv.jp/meteor5/ssm1.png)
4. 最後に、ClientIDとClient secretを入力して「Save Configuration」をクリック

こんな感じの手順になります。
ここまでできたら、画面が下記のように変わっているはずです。

![Google設定終わったとき](http://img.dfm.lrv.jp/meteor5/ss2.png)

うまくいきましたか？
めっちゃ **accounts-uiが教えて** くれましたね！w

#### 続けてTwitterも！

勢い良く、Twitterもやっちゃいましょう。
Googleの設定が終わって戻ってきた、先ほどの画面から、

1. 「Configure Twitter Login」をクリック
2. さらにポップアップが出てくるので、あとは書いてある通りにやる。
3. 最後に、ClientIDとClient secretを入力して「Save Configuration」をクリック

![Twitter設定手順1](http://img.dfm.lrv.jp/meteor5/ssm2.png)

もちろん、

![両方設定終わった](http://img.dfm.lrv.jp/meteor5/ss3.png)

こんな風に設定されましたよね！
これで「`twtest`にGoogleとTwitterのIDを使ってログインするための設定」は完了です。

### ログインしてみる。

設定がようやく終わったので、早速使ってみましょう。

とりあえず、「Sign in with Twitter」を押してみてください。
すると、下記のようになるはずです。

![認証画面](http://img.dfm.lrv.jp/meteor5/ss4.png) 

認証画面ですので、ここでTwitterのIDとパスワードを入力してください。
うまくいくと、

![ログイン完了画面](http://img.dfm.lrv.jp/meteor5/ss5.png)

こんな感じでログインできました！

### OAuthについて

GoogleやTwitterアカウントを使ったログインは、OAuthという仕組みを使って実現しています。

OAuthは複数のアプリケーションが連携してユーザー認証を行うための仕組みです。
かなり、ややこしい仕組みで実現しているのですが、Meteorが、その**ややこしい仕組みを肩代わりしてくれている** というわけです。

OAuthについて詳しく知りたい方は、下記リンクを参照してみてください。

- [ゼロから学ぶOAuth](http://gihyo.jp/dev/feature/01/oauth/0001)
- [第1回　「OAuth」の基本動作を知る](http://www.atmarkit.co.jp/fsecurity/rensai/digid01/01.html)

さきほど「Configure Google Login」「Configure Twitter Login」の最後に入力した情報は、Meteorがデータベースに保存し、OAuthを使ったやりとりの際に使っているようです。

## ログイン前と後で表示を切り替えるよう改造してみる

ここまでで、とりあえずログインできる機能は追加されましたが、**まだコードを1行しか書いてない** こともあり、ログイン前後に変化がなくて寂しいです。
せっかくGoogleやTwitterでログインできるようになったので、ログイン後はアイコンを表示するように、改造してみたいと思います。

[前回](http://qiita.com/tadfmac/items/714654958c127c053d51)は、同じようなことを実施するのに、`Meteor.userId()`でログイン状態を判定し、その変化タイミングを`Deps.autorun()`で取得、という流れでプログラミングしました。
これはこれで、様々なコレクションに応用できる方法なので、今回も同じやりかたで実現しても良いのですが、今回のようにログインしてるかどうかだけの判定であれば、テンプレートを使って、もう少し簡単に書くことができます。

### `{{#if currentUser}}`で分岐する

テンプレートでログイン状態の判定を行うには、[`{{currentUser}}`](http://docs.meteor.com/#template_currentuser)を利用します。
`{{currentUser}}`は、`Meteor.user()`をテンプレートから呼び出すものです。`Meteor.user()`は、ログインしていればユーザーデータを返し、ログインしていなければ、`null`を返却するので、テンプレートの`{{#if }}`と併用してログイン済か否かが判定できるわけです。

さっそく、htmlを書き換えてみましょう。

今回は、GoogleとTwitterそれぞれでログインすることができるので、どちらでログインしたかの判定も必要になります。
ログインに外部サービス連携を利用した場合、Meteor.user()で返却されるオブジェクトに含まれる、`services`というオブジェクトに、ログインに利用したサービスのオブジェクトが格納されるようです。

- Googleであれば、`currentuserdata.services.google`
- Twitterであれば、`currentuserdata.services.twitter`

というわけで、上記に対応してみましょう。

```twtest.html
<head>
  <title>twtest</title>
</head>

<body>
<div>{{> loginButtons}}</div>

  {{#if currentUser.services.google}}
  	{{> google}}
  {{/if}}
  {{#if currentUser.services.twitter}}
  	{{> twitter}}
  {{/if}}

  {{> hello}}

</body>

<template name="twitter">
  <div><img src="{{currentUser.services.twitter.profile_image_url}}"></div>
</template>

<template name="google">
  <div><img src="{{currentUser.services.google.picture}}"></div>
</template>

<template name="hello">
  <h1>Hello World!</h1>
  {{greeting}}
  <input type="button" value="Click" />
</template>
```

ログイン状態によって、表示させるテンプレートを切り替えるようにしてみました。
これで、ログイン後、GoogleやTwitterアカウントに設定した画像が表示されるはずです。

![アイコンを表示するように変えてみた](http://img.dfm.lrv.jp/meteor5/ss6.png)

## `accounts-ui`のconfigurationは便利だけど。。。

ここまでで、最初に「Configure Google Login」「Configure Twitter Login」を行えば、GoogleやTwitterにログインできるようになりました。
でも、一度覚えてしまうと、何回もこれをやるのは面倒ですよね？！
というか、サイトの運用として、ちょっとヘンテコです。手作業なしに設定したいものです。

というわけで、アプリ起動時に自動的にconfigurationするよう改善してみます。

> GoogleやTwitterへのアプリ登録は別途必要です。
> 慣れるまでは今回のように`accounts-ui`と「Configure Google Login」「Configure Twitter Login」を使ってアプリ登録する方が間違いが少ないと思います。

### Meteor.startup()を使ってアプリ起動時に必要な情報を設定する

GoogleやTwitterなどの外部サービスの設定情報は、`Accounts.loginServiceConfiguration`コレクションに保存されています。
起動時に、ここに情報を設定するようにしましょう。

> GoogleとTwitterで、設定する情報が異なるので注意してください。

コードは下記のようになります。

```twtest.js
if (Meteor.isClient) {
	// : 省略
}

if (Meteor.isServer) {
  Meteor.startup(function() {
    Accounts.loginServiceConfiguration.remove({service:'twitter'});
    Accounts.loginServiceConfiguration.remove({service:'google'});
    Accounts.loginServiceConfiguration.insert({
      service:'twitter',
      consumerKey:'(API KEY)',
      secret:'(API secret)'
    });
    Accounts.loginServiceConfiguration.insert({
      service:'google',
      clientId:'(CLIENT ID)',
      secret:'(CLIENT SECRET)'
    });
  });
}
```

これで、最初から

![両方設定終わった](http://img.dfm.lrv.jp/meteor5/ss3.png)

が表示されるようになったはずです。

## いよいよ最後。グローバルアドレスでも動くようにするには?

これまで、`localhost:3000` で動作するサイトを作ってきました。
GoogleやTwitterに登録したコールバックURLなども、`	http://127.0.0.1:3000/_oauth/twitter?close`のような、ローカルIPになっています。
外部サーバでもGoogleやTwitterのアカウントでログインできるようにしてみましょう。

### GoogleやTwitterのアプリ設定画面で、コールバックURLを書き換える

まず、GoogleとTwitterに登録した`Callback URL`を、インターネットからアクセス可能なグローバルなURLに書き換えてください。

- [Google](https://console.developers.google.com/project/)
- [Twitter](https://apps.twitter.com/app/)

### 重要！：サーバにプロジェクトを置いて実行する

レンタルサーバなどで、Meteorが動作する環境を作って、Meteorを実行してください。
このとき、`meteor` と入力するだけだと、うまくいきません。

> Meteorは、コールバックURLにmeteorが実行されているルートURLを指定してしまいます。何も指定していないときは、localhost:3000 になります。
> ルートURLを指定しても、Meteorは、開発用モードだとこれを無視します。

ということなので、

- ルートURLに、グローバルURLを指定する
- プロダクションモードを指定する
- リバースプロキシ経由でアクセスするサイトの場合、ルートURLにはアクセスして欲しいURLを、ポート指定で内部URLを指定する

が必要になります。
このため、下記のようにコマンドラインから入力します。

```
> ROOT_URL=http://app.example.com meteor --port example.com:4000 --production
```

上記は、リバースプロキシを使って、http://app.example.com を http://example.com:4000 に飛ばす設定がしてある場合の実行方法になります。

> ここが判らず、半日費やしました :(

## まとめ

おつきあいいただきありがとうございます。

今回は、Meteorを使ってGoogleやTwitterのアカウントでログインする方法を見てきました。
私はアカウントを持ってませんが、Facebookとかも同じようにできると思います。ぜひやってみてください！
また、変なところ、間違い、補足、ご意見など、募集しています！いろいろ教えてください！！

改めて、本当に、Meteorって最初の敷居が超低い！と実感した今回でした。

というわけで、Meteorはv1.0になるまでは少なくとも、いろいろ見ていきたいと思いますので、よろしくお願いします。


## バックナンバーと続き

Meteor 1.0が出ましたので、バックナンバーと続きの記事をまとめました！
下記もよろしくお願いします！

[JavaScript超初心者向け Meteor メモ (1)](http://qiita.com/tadfmac/items/a63bb85e5cfb12bbbfc8)
[JavaScript超初心者向け Meteor メモ (2) v0.8.0でのテンプレートエンジンの変更について](http://qiita.com/tadfmac/items/823fd909bf3af2f6c7b7)
[JavaScript超初心者向け Meteor メモ (3) シンプルなチャットを作ってみる](http://qiita.com/tadfmac/items/e7e0d95b2affcf2438a9)
[JavaScript超初心者向け Meteor メモ (4) ログイン画面を作る （基本編）](http://qiita.com/tadfmac/items/714654958c127c053d51)
[JavaScript超初心者向け Meteor メモ (6) 外部パッケージを使ってみる](http://qiita.com/tadfmac/items/48d160ecba779237c771)
[JavaScript超初心者向け Meteor メモ (7) テンプレートを使ってみる](http://qiita.com/tadfmac/items/2b5e111e8986fc98f6f8)