Gatsby(React)で超絶簡単にSNS認証をして動的にユーザーページを生成する
13分目次
- 出来上がるもの
- 環境
- Gatsby で新規サイト作成する
- プラグインのインストール
- firebase の設定
- .env ファイルの作成
- プラグインの設定
- index.js の編集 ①
- ローカルサーバーを建てる
- 動的にページを生成する
- index.js の編集 ②
出来上がるもの
https://socail-login-react.netlify.app/
トップページにはボタンだけ設置しました。Google でしかログインできない状態ですが Twitter や FaceBook による認証も簡単に行えます。やってないのは僕が developer アカウントを紐づけている SNS アカウントを削除してしまったからです……。また取得し次第こちらのデモに追加したいと思います(覚えていたら)。
ボタンをクリックすると、ログインユーザーとなり、uid によって動的にページが生成されます。よくある Web アプリと同じですね。
環境
- Node v10.15.3
- Gatsby v2.23.14
- React v16.12.0
その他詳細はpackage.json参照。
それでは作っていきます。
Gatsby で新規サイト作成する
gatsby new social-login-test
gatsby new
コマンドを使えない人は下記を先に入力しましょう(node.js も必要です)。
npm install -g gatsby-cli
Gatsby サイトの生成は少々時間がかかります。生成が終わったらディレクトリに移動しましょう。
cd social-login-test
プラグインのインストール
yarn add gatsby-theme-firebase
ソーシャルログインを超絶簡単に行えるようにするためのプラグインがgatsby-theme-firebase
です。Gatsby で Firebase を使おうとすると面倒な手順を踏まなければいけないのですがそれらを簡略化してくれ、プラグインをインストールするだけでほとんど何もせずに SNS による認証画面や認証機能ができあがります。
firebase の設定
いったんエディターを閉じ、ブラウザを開き、firebase のキーを取得していきます。
firebase の利用には Google アカウントが必要です。料金はかかりません
firebase にアクセスしたらヘッダー右上にあるコンソールへ移動ボタンをクリックし、新規プロジェクトを作成します。
プロジェクト作成手順が 2 つほどありますが面倒なことは何もありません。任意のプロジェクト名を入力し、
アナリティクスを使うかを設定するだけです。
今回はサンプルなのでオフにしていますがオンにしても構いません
ここまでいくと自動的にダッシュボードに遷移します。今回使用する firebase の機能は認証機能なので、左のツールバーからAuthentication
を選択しましょう。
Authentication では様々な認証方法が用意されています。前述したように僕は Facebook や Twitter の dev アカウントを削除してしまっているためそれらの認証を使いませんでしたが、使用しても全く問題ありません。その場合は各 SNS の dev アカウントで API キーを取得しましょう。Google 認証だけで構わない場合は Google アカウントによる認証を有効化して自分のメアドを入力すればすぐに使えるようになります。便利ー!
ここまで終わったら firebase のキーを取得します。左のツールバー家アイコンからホームに戻り、</>ボタンを押しましょう。
この firebase プロジェクトを紐づけるウェブサイトの名前を入力します(適当で OK)。そうするとコードが表示されるのでそれをコピーしましょう。
これらのキーを直接見えるところに置くのはセキュリティ的によろしくないため、.env ファイルを作っていきます。
.env ファイルの作成
エディターに戻り、ルート直下に.env
ファイルを作成し、先ほどコピーしたコードを貼り付けます。
必要なのは上画像のハイライト部分だけなので、var firebaseConfig = {}
の中身以外は削除し、中身は下画像のように書き換えます。
FIREBASE_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
FIREBASE_AUTH_DOMAIN=XXXXXXXXXXXXXX.firebaseapp.com
FIREBASE_DATABASE_URL=https://XXXXXXXXXXXXXX.firebaseio.com
FIREBASE_PROJECT_ID=XXXXXXXXXXXXXXXXXXXXX
FIREBASE_STORAGE_BUCKET=XXXXXXXXXXXXXXXXXX.appspot.com
FIREBASE_MESSAGING_SENDER_ID=0123456789123456789
FIREBASE_APP_ID=1:1234567890:web:XXXXXXXXXXXXXXXXXX
プラグインの設定
Gatsby ではプラグインの細かい設定をgatsby-config.js
から行えます。また、gatsby-config.js
は node.js により動くため、node.js 形式で書いていく必要があります。まず、ファイル先頭に下記のコードをコピペしましょう。
require("dotenv").config({
path: `.env`,
});
.env ファイルで定義された変数を使用するために dotenv というモジュールを使用します(インストール等は必要ありません)。
つづいてplugins: []
の配列の中に下記を追記しましょう。
module.exports = {
siteMetadata: {
// 略
},
plugins: [
{ resolve: "gatsby-theme-firebase", options: { credentials: { apiKey: process.env.FIREBASE_API_KEY, authDomain: process.env.FIREBASE_AUTH_DOMAIN, databaseURL: process.env.FIREBASE_DATABASE_URL, projectId: process.env.FIREBASE_PROJECT_ID, storageBucket: process.env.FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID, appId: process.env.FIREBASE_APP_ID, }, socialLogins: ["google"], // Googleアカウント認証の場合はこう // 他の認証も使いたい場合は配列内に追記 // socialLogins: ["google", "twitter", "facebook", "github"] },
},
// 略
],
};
コメントアウトでも書いていますが、今回僕は Google アカウントによる認証だけなのでsocialLogins
の配列の中は google だけですが、Twitter や FaceBook などによる認証も追加したい場合はsocialLogins: ["google", "twitter", "facebook", "github"],
といった具合で追加しましょう。
ここまでできていたらコードはこんな感じになっているかと思います(plugins
の配列の中の順序が異なっていても問題ありません)。
index.js の編集 ①
src/pages/index.js
を開き、上画像のように不必要な部分を削除します。その後、ファイル先頭で以下のように import をします。
import { auth, useAuth, SocialLogins } from "gatsby-theme-firebase";
続いて関数コンポーネント内で、下記のように定義します。
const IndexPage = () => {
const { isLoggedIn } = useAuth(); // 省略
};
useAuth()
のソースはこちら。isLoggedIn
でログイン状態かどうかの判断を行います。
では実際にログインボタンとログアウトボタンを追加します。gatsby-theme-firebase
がコンポーネントを用意してくれているのでそれを配置するだけです。
const IndexPage = () => {
const { isLoggedIn } = useAuth();
return (
<Layout>
<SEO title="Home" />
{!isLoggedIn && (
<SocialLogins
onSuccess={(user) => {
console.log(user);
}}
/>
)}
{isLoggedIn && <button onClick={() => auth.signOut()}>ログアウト</button>}
</Layout>
);
};
{!isLoggedIn && (...)}
の部分はワンライナーの if 文です。
!
は否定なので、ログインしていないときにログインボタンを表示するという仕様にしています。逆にログイン状態であればログアウトボタンを表示します。
ローカルサーバーを建てる
ここまで実装できたらターミナルでgatsby develop
またはyarn develop
を実行し、ローカルサーバーを立てます。1 分ほど待つと、ローカルサーバーが立ち上がるのでアクセスしましょう。
こんな感じになっているかと思います。
ログインし、コンソールを開いてみましょう。
Object の中の user プロパティの中に名前やメールアドレス、画像の URL を確認することができました。また、一意の ID である uid も確認できます。これらを使用すればユーザーページを作っていくことができます。
動的にページを生成する
動的にページを生成するのには@reach/router
を使用します。
まずはインストールからです。
yarn add @reach/router
インストールができたら src/pages に user.js を新規作成し、ここを起点として動的にページを精製していきましょう。
import React from "react";
import { Router } from "@reach/router";
import Layout from "../components/layout";
const User = () => {
return (
<Layout>
<Router></Router>
</Layout>
);
};
export default User;
次にプロフィール部分を担う Profile コンポーネントを作っていきます。/src/components に Profile.js を新規作成しましょう。
import React from "react";
import { useAuth } from "gatsby-theme-firebase";
const Profile = () => {
const { isLoggedIn, profile } = useAuth();
console.log(profile);
return (
<>
{isLoggedIn && (
<>
<p>お名前: {profile.displayName}</p>
<p>
<img src={profile.photoURL} width="150" />
</p>
</>
)}
</>
);
};
export default Profile;
profile
には認証済みユーザーが格納されています。コンポーネントができたので、user.js を編集しましょう。動的生成するページはこの Profile コンポーネントを利用します。
profile
は isLoggedIn 内では動作しますが、それ以外だとnull
を返します。そのためログインしていないユーザーでも閲覧できるようなユーザーページなどを作りたい場合には別のオブジェクトを使用したり別のアプローチを取ったりなどの必要がありそうです。
import React from "react";
import { Router } from "@reach/router";
import Layout from "../components/layout";
import Profile from "../components/Profile";
const User = () => {
return (
<Layout>
<Router>
<Profile path="/user/:uid" />
</Router>
</Layout>
);
};
export default User;
最後に動的生成するための処理をgatsby-node.js
に書いていけば動的生成が可能となります。
ちなみにこちらのファイルも node.js 製です。gatsby-*.js
は node.js と思って良さそうですね。
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions;
if (page.path.match(/^\/user/)) {
page.matchPath = "/user/*";
createPage(page);
}
};
gatsby-node や gatsby-config を編集した後はサーバーを再起動する必要があります。Ctrl + Cでサーバーを一旦停止し、gatsby develop
で再起動させましょう。
トップページにアクセスし、ログインをしていたらログアウトしましょう。そして再度ログインをして console を開きます。ログインをすると console に object を表示しているようにしてあるので、そこから uid を取得し、コピーしましょう。
http://localhost:8000/user/ここにuid
/user/
のあとにコピーした uid をペーストし、アクセスしてみてください。
Google アカウントの名前と画像が表示されていればうまく動作しています。
index.js の編集 ②
最後にログイン後にリダイレクトするようにします。リダイレクトは Gatsby が用意してくれているnavigate
ヘルパーを利用すれば可能です。index.js を下記のように編集しましょう。
import React from "react";
import { navigate } from "gatsby";
import Layout from "../components/layout";
import Image from "../components/image";
import SEO from "../components/seo";
import { auth, useAuth, SocialLogins } from "gatsby-theme-firebase";
const IndexPage = () => {
const { isLoggedIn } = useAuth();
return (
<Layout>
<SEO title="Home" />
{!isLoggedIn && (
<SocialLogins
onSuccess={(user) => {
navigate(`/user/${user.user.uid}`); }}
/>
)}
{isLoggedIn && <button onClick={() => auth.signOut()}>ログアウト</button>}
</Layout>
);
};
export default IndexPage;
ここまで済んだらローカルサーバーにアクセスし、再度トップページに戻り、ログアウトし、再度ログインします。ログイン時にうまくリダイレクトされれば機能の実装は終了です。Yay!