Svelte + で開発している個人アプリに認証機能が必要になり、導入の容易さ等からfirebase authenticationを導入しました。
その時の手順・やったことを備忘のため残しておきます。
この記事で作成するアプリのサンプルコードは以下でも公開しています。
1. 下準備
実装の前にfirebase側で下準備をします。
ウェブアプリをプロジェクトに追加します。任意の名称を指定してください。
アプリケーションの作成が完了しました。
このコンフィグは次の手順で使用するのでコピペして保管しておいてください。
次にGoogleアカウントによる認証機能をONにします。authentication
をクリックしてください。
これでfirebase側の設定は完了です。
2. Svelte+TypeScriptプロジェクトの作成
以下の手順で公式のテンプレートからプロジェクト作成します。
今回、プロジェクト名はsvelte-typescript-auth-app
とします。
npx degit sveltejs/template svelte-typescript-auth-app
無事にプロジェクトが作成されたら、プロジェクト内に移動してTypeScriptを適用します。
cd svelte-typescript-auth-app
node scripts/setupTypeScript.js
3. プロジェクトの下準備
npmライブラリのインストール
今回は以下のnpmライブラリを使います。
名称 | 用途 |
---|---|
svelte-routing | このアプリケーションでは複数ページを扱う予定ですので、Vue RouterやReact Routerのようなルーティングライブラリを導入します。 |
firebase | firebase公式が提供しているSDKになります。今回はこちらを利用してfirebaseを用いた機能を実装していきます。 |
プロジェクト配下で以下のコマンドでインストールしてください
npm i svelte-routing firebase
sirvコマンドにオプションを設定
今回はSPAとして実装するので、package.json
の以下箇所に--single
オプションを設定してください。
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public --no-clear --single", // TODO 追加
"check": "svelte-check --tsconfig ./tsconfig.json"
},
4. firebase.tsの作成
下準備で保存しておいた情報でfirebase.tsを作成します。
この設定情報を読み込ませたクラスを作成し、認証で使うクラス群をexportします。
import { initializeApp } from "firebase/app";
import { getAuth, GoogleAuthProvider } from "firebase/auth";
const firebaseConfig = {
// TODO READMEの手順で作成した情報をコピペしてください。
apiKey: "your api key",
authDomain: "your auth domain",
projectId: "your project id",
storageBucket: "your strage bucket",
messagingSenderId: "your messaging sender id",
appId: "your app id"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export const provider = new GoogleAuthProvider();
5. AuthStoreの作成
ログイン情報を保持するStoreクラスを作成します。
import type { UserInfo } from "firebase/auth";
import { writable } from "svelte/store";
export const authStore = writable({ loggedIn: false, user: null as UserInfo });
6. 画面の作成・ルーティング設定
ログイン画面とマイページ画面(ログイン後に遷移する画面)を作成します。
実際の認証周りの処理はこの後実装していきます。
<script lang="ts">
import { navigate } from "svelte-routing";
function handleLoginWithGoogle() {
// TODO TBD
navigate("/mypage");
}
</script>
<div>
<button type="button" on:click={handleLoginWithGoogle}>
Sign In with Google
</button>
</div>
<script>
import { navigate } from "svelte-routing";
import { authStore } from "./store";
function handleLogout() {
// TODO TBD
navigate("/");
}
</script>
<h1>Login successed.</h1>
<ul>
<li>email:</li>
<li>name:</li>
</ul>
<button type="button" on:click={handleLogout}> Logout </button>
ログイン画面とマイページ画面のルーティングを設定します。
<script lang="ts">
import { Route, Router } from "svelte-routing";
import Login from "./Login.svelte";
import Mypage from "./Mypage.svelte";
</script>
<Router>
<Route Path="/" component={Login} />
<Route path="/mypage" component={Mypage} />
</Router>
ここまでで画面はこんな感じになっていると思います。
7. ログイン機能の作成
先に作成した画面にfirebaseによるログイン機能を実装していきます。
まずはログイン画面からやっていきます。
handleLoginWithGoogle
関数にログイン処理を実装しました。
firebase SDKで公開されているsignInWithPopup
関数にfirebase.ts
でexportしたauth
とprovider
を引数で渡して実行する流れになります。
ログインできたらログイン情報をStoreに保存してMypageへ遷移します。
<script lang="ts">
import { navigate } from "svelte-routing";
import { signInWithPopup } from "firebase/auth";
import { auth, provider } from "./firebase";
import { authStore } from "./store";
async function handleLoginWithGoogle() {
await signInWithPopup(auth, provider)
.then((res) => {
authStore.set({ ...$authStore, loggedIn: true, user: res.user });
navigate("mypage");
})
.catch((e) => {
console.log(e);
});
}
</script>
<div>
<button type="button" on:click={handleLoginWithGoogle}>
Sign In with Google
</button>
</div>
次にMypageにもログアウトの処理・認証済・未済のハンドリング処理を実装します。
<script>
import { navigate } from "svelte-routing";
import { auth } from "./firebase";
import { authStore } from "./store";
function handleLogout() {
auth.signOut();
navigate("/");
}
</script>
<h1>Login successed.</h1>
{#if $authStore.loggedIn}
<ul>
<li>email: {$authStore.user.email}</li>
<li>name: {$authStore.user.displayName}</li>
</ul>
<button type="button" on:click={handleLogout}> Logout </button>
{/if}
8. 動作確認
もう一度npm run dev
コマンドでアプリを再起動し、ログインボタンを押下すると、以下のようなダイアログが表示されてGoogleアカウントでログイン認証ができるはず!