Firebase AuthenticationでReactアプリにTwitter/Facebook/Google認証をつける


Firebase Authenticationを使うとTwitter, Facebook, Googleでのログインを極めて簡単に実装できます。

例としてReactのSPAに対して、Twitterによる認証認可を組み込んでみます。

## Twitterでアプリ作成

1. Apps for Twitterでアプリ作成

	https://apps.twitter.com で新規アプリを作成します。
		
2. Consumer KeyとConsumer Secretの確認

Consumer Key(API Key)とConsumer Secret(API Secret)を取得します。

![twitter.png](https://qiita-image-store.s3.amazonaws.com/0/15414/ee5a5f38-5b0a-d01f-43e3-818b672fb362.png "twitter.png")
	
3. E-mail

Firebase AuthenticationでTwitterのE-mailアドレスを取得する場合は次の設定をします。
	
Settingで **Privacy Policy URL** と **Request email addresses from users** を設定する。

Permissionsで 

![permission.png](https://qiita-image-store.s3.amazonaws.com/0/15414/4824dd9d-737f-ce55-11f6-0fe1d9fefd70.png "permission.png")

## FirebaseのWebコンソール

1. FirebaseのWebコンソールを開いて、AuthenticationタブからTwitterを有効化します。

![firebase_authentication.png](https://qiita-image-store.s3.amazonaws.com/0/15414/6ce213cf-d849-e6d5-1a34-4bd16ad6719a.png "firebase_authentication.png")

2. APIキーとAPIシークレットにTwitterのページのAPI KeyとAPI Secretを入力して保存します。

3. このページのコールバックURLをTwitterのCallback URLに入力します。


## Reactアプリの作成

[React & Flux入門](https://qiita.com/sl2/items/ff7a07c00f545d245a5c)で紹介しているツールを使います。

```
npx starter-react-flux init
npm start
```

## 認証認可の実装

1. FirebaseのSDKの追加

	```
	npm install --save firebase
	```

2. configの作成

	`app/config.js`を新規作成します。
	
	```js
	import firebase from 'firebase/app';
	import 'firebase/firestore'; //firestoreを使う場合
	import 'firebase/auth';
	
	firebase.initializeApp({
	  apiKey: '*****',
	  authDomain: '*****',
	  projectId: '*****'  
	});
	
	export const providerGoogle = new firebase.auth.GoogleAuthProvider();
	export const providerFacebook = new firebase.auth.FacebookAuthProvider();
	export const providerTwitter = new firebase.auth.TwitterAuthProvider();
	export const db = firebase.firestore(); //firestroeを使う場合
	export default firebase;
	```

3. ページにログイン、ログアウトボタンとそれぞれのハンドラを追加します。

	`app/components/Content.js`
	
	```js
		略
	  handleLogin = () => {
	    SampleActionCreator.loginWithTwitter();
	  }
	
	  handleLogout = () => {
	    SampleActionCreator.logout();
	  }
	
	  render() {
	    return (
	      <div style={this.props.style}>
	           略
	        <Button onClick={this.handleLogin}>Login</Button>
	        <Button onClick={this.handleLogout}>Logout</Button>        
	      </div>
	    );
	  }
	```

4. Action Creatorでログインやログアウトを実装します。

	```js
	import firebase, { providerTwitter } from '../config';
	
		略
	
	  loginWithTwitter() {
	    firebase.auth().signInWithRedirect(providerTwitter);
	    firebase.auth().getRedirectResult().then(result => {
	      console.log(result);
	      //TODO: ex. storeに送信, DB保存,...
	    }).catch(error => {
	      console.log(error);
	    });
	  },  
	```
	
Fluxについては[React & Flux入門](https://qiita.com/sl2/items/ff7a07c00f545d245a5c)に書いているので割愛します。      

ログイン状態に応じて表示コンポーネントを切り替える方法は色々あるので割愛します。

5. デプロイして確認

	```sh
	npm runb build && firebase deploy
	```

	![login.gif](https://qiita-image-store.s3.amazonaws.com/0/15414/5f0430e8-bb9c-ef31-8434-a1e22042fd45.gif "login.gif")
	
	ログインするとWebコンソールでユーザーが確認できます。
	
	![twitter-a.png](https://qiita-image-store.s3.amazonaws.com/0/15414/33836044-4b16-0c4a-7215-42f793042628.png "twitter-a.png")
	

## Google, Facebook

OAuthのスコープなど細かな設定は各プロバイダに合わせる必要がありますが、まったく同じ方法でいけます。

### Google

```
import { providerGoogle } from '../config';
  :
firebase.auth().signInWithRedirect(providerGoogle);
```

### Facebook

```
import { providerFacebook } from '../config';
  :
firebase.auth().signInWithRedirect(providerFacebook);
```

## Tips

### ログイン中のユーザー

```
firebase.auth().onAuthStateChanged(user => {
  console.log("onAuth", user);
});

or 

const current user = firebase.auth().currentUser
```

### ログアウト(Firebaseから)

```
firebase.auth().signOut().then(result => {
	console.log(result);
}).catch(error => {
	console.log(error);
});
```

### その他

認証認可やユーザー管理に関するかなりの機能が簡単に実装できます。

- ユーザー管理 https://firebase.google.com/docs/auth/web/manage-users?hl=ja
	- 確認メール送信、ユーザーの詳細情報取得、再認証、etc
- アカウントのリンク https://firebase.google.com/docs/auth/web/account-linking?hl=ja
	- 初回は匿名ユーザで使わせてあとから認証ユーザへのアップデートする場合など
- 認証の有効期間 https://firebase.google.com/docs/auth/web/auth-state-persistence?hl=ja