
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、私は新しい情報を取得できるようにニュースやブログだけでなく、海外の掲示板もチェックするよう心掛けています。
そして、そんな中でたびたび登場するあるキーワードがあって、「時間ができたら試してみよう!」と考えていました。
それは、
サーバーレス
です。
サーバーレスとは、簡単に言うと「サーバー管理はクラウドにおまかせ!」という意味で、サーバー管理の手間を省けるというのが大きなメリットです。
そして!
そんなサーバーレスを実装するサイトはいくつかありますが、私が気になっていたのはよく話題になるGoogle
の「Firebase」です。
そこで、今回はFirebase
を使ってログイン関連の機能をつくってみます。
ぜひ皆さんのお役に立てると嬉しいです
開発環境: Firebase JavaScript SDK 7.12.0
目次 [非表示]
Firebaseの準備
プロジェクトをつくる
まずFirebase
にログインして「プロジェクトを作成」ボタンをクリックしてください。(すみません、登録はその昔にやってしまったので省略させてください)
プロジェクトの名前を入力し、規約の同意にチェックを入れたら「続行」ボタンをクリックします。
次にアナリティクスを使うかどうか聞かれますが、今回はテストなのでチェックを外して「プロジェクトを作成」ボタンをクリック。
すると、新しいプロジェクトが作成されます。
プロジェクトの設定
続いてJavaScript
でFirebase
を使えるようにします。
</>
ボタンをクリックしてください。
そして、アプリの名前を入力して「アプリを登録」ボタンをクリックします。
すると、JavaScript
コードが表示されますが、この中のfirebaseConfig
の内容は後で必要になってきますので、控えておいてください。
そして、「コンソールに進む」ボタンをクリックします。
続いてプロダクトを「Authentication」をクリック。
そして、「ログイン方法を設定」をクリック。
Firebase
には認証方法がたくさんありますが、今回は基本的な「メールアドレス + パスワード」を選択します。
すると、以下のようなポップアップが表示されるので「有効にする」にチェックを入れて「保存」ボタンをクリックしてください。
これでFirebase
の準備は完了です!
ログイン、ログアウト、ユーザー登録機能をつくる
では、実際にコードを書いていきましょう。
まずは、基本になる以下3つの機能です。
- ログイン
- ログアウト
- ユーザー登録
auth.html
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div id="app" class="container pt-3">
<div v-if="sending">
送信中...
</div>
<div v-if="user">
<h1>ログインが成功しました</h1>
<button type="button" class="btn btn-primary mb-3" @click="logout">ログアウト</button>
<pre class="bg-light p-3" v-text="user"></pre>
</div>
<div class="row">
<div class="col-6">
<div class="form-group">
<label>メールアドレス</label>
<input type="text" class="form-control" v-model="email">
</div>
<div class="form-group">
<label>パスワード</label>
<input type="password" class="form-control" v-model="password">
</div>
<div class="form-group">
<button type="button" class="btn btn-danger mr-3" :disabled="sending" @click="register">ユーザー登録</button>
<button type="button" class="btn btn-primary" :disabled="sending" @click="login">ログイン</button>
</div>
</div>
</div>
</div>
<script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-auth.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
email: '',
password: '',
user: null,
sending: false
},
methods: {
register() {
this.sending = true;
firebase.auth()
.createUserWithEmailAndPassword(this.email, this.password)
.catch(error => { // エラーの場合
alert('登録情報が正しくありません。');
})
.finally(() => {
this.sending = false;
});
},
login() {
this.sending = true;
firebase.auth()
.signInWithEmailAndPassword(this.email, this.password)
.catch(error => { // エラーの場合
alert('ログイン情報が間違っています。');
})
.finally(() => {
this.sending = false;
});
},
logout() {
firebase.auth().signOut();
}
},
mounted() {
// firebaseを準備
const firebaseConfig = {
apiKey: "**********************************",
authDomain: "**********************************",
databaseURL: "**********************************",
projectId: "**********************************",
storageBucket: "**********************************",
messagingSenderId: "**********************************",
appId: "**********************************"
};
firebase.initializeApp(firebaseConfig);
// ログイン状態が変化したら実行
firebase.auth().onAuthStateChanged(user => {
if(user) {
this.user = user;
this.email = '';
this.password = '';
} else {
this.user = null;
}
});
}
});
</script>
</body>
</html>
この中で重要なのがmounted()
内にあるfirebaseConfig
の部分です。
ここは、先ほどFirebase
の準備で取得したものを使ってください。
そして、その下にあるonAuthStateChanged()
はログイン状態が変化すると実行される部分で、例えばログインやユーザー登録に成功したり、ログアウトした場合に呼ばれることになります。
また、実際にユーザー登録しているのはcreateUserWithEmailAndPassword()
で、ログインはsignInWithEmailAndPassword()
になり、ユーザー情報がVue
で表示されることになります。(ちなみに、ユーザー登録した時点でログインも完了しています)
ユーザー情報を更新する
先ほどのユーザー登録ではメールアドレスとパスワードだけを登録しましたが、Firebase
では、その他のデータも保存できます。
そこで、今回は「ユーザー名」を登録してみます。
※なお、もちろんHTMLファイルで実行可能ですが、先にログインをしてから実行してください。
update.html
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div id="app" class="container pt-3">
<div v-if="sending">
送信中...
</div>
<div class="row" v-if="user">
<div class="col-6">
<h1>名前を追加してください</h1>
<div class="form-group">
<input type="text" class="form-control" v-model="userName">
</div>
<button type="button" class="btn btn-primary" @click="save">保存する</button>
</div>
<div class="col-6">
<h1>ユーザー情報</h1>
<pre class="bg-light p-3" v-text="user"></pre>
</div>
</div>
</div>
<script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-auth.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
userName: '',
user: null,
sending: false
},
methods: {
save() {
this.sending = true;
if(this.user){
this.user.updateProfile({
displayName: this.userName
})
.catch(error => {
alert('失敗しました。');
})
.finally(() => {
this.sending = false;
});
}
}
},
mounted() {
// firebaseを準備
const firebaseConfig = {
apiKey: "**********************************",
authDomain: "**********************************",
databaseURL: "**********************************",
projectId: "**********************************",
storageBucket: "**********************************",
messagingSenderId: "**********************************",
appId: "**********************************"
};
firebase.initializeApp(firebaseConfig);
// ログイン状態が変化したら実行
firebase.auth().onAuthStateChanged(user => {
if(user) {
this.user = user;
} else {
this.user = null;
}
});
}
});
</script>
</body>
</html>
この中で実際にFirebase
へデータ送信しているのが、updateProfile()
です。そして、displayName
がユーザー名のフィールドになります。
パスワード再発行
では、最後にパスワードを再発行する機能をつくっていきましょう。
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>
<div id="app" class="container pt-3">
<div class="row">
<div class="col-6">
<h1>パスワード再発行</h1>
<div class="form-group">
<label>メールアドレス</label>
<input type="text" class="form-control" v-model="email">
</div>
<button type="button" class="btn btn-primary" @click="send">送信する</button>
</div>
</div>
</div>
<script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.12.0/firebase-auth.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script>
new Vue({
el: '#app',
data: {
email: ''
},
methods: {
send() {
firebase.auth().languageCode = 'ja'; // 日本語に設定
firebase.auth()
.sendPasswordResetEmail(this.email)
.then(() => {
alert('パスワード再発行URLを送信しました。');
}).catch(error => {
alert('該当するデータが見つかりませんでした。');
});
}
},
mounted() {
// firebaseを準備
const firebaseConfig = {
apiKey: "**********************************",
authDomain: "**********************************",
databaseURL: "**********************************",
projectId: "**********************************",
storageBucket: "**********************************",
messagingSenderId: "**********************************",
appId: "**********************************"
};
firebase.initializeApp(firebaseConfig);
}
});
</script>
</body>
</html>
コード的にはボタンが押されたらsendPasswordResetEmail()
が実行されるシンプルなものです。
このメソッドが実行されるとFirebase
の方から次のような再発行メールが届きますので、パスワードを変更する場合はURLをクリックします。
すると以下のようなフォームが表示されるのでパスワードを送信。
Firebase
がパスワードを変更してくれます。
おわりに
ということで今回はサーバーレスなログイン機能を作ってみました。
個人的にサーバーレスは初めての経験でしたが、HTMLファイルさえあれば実行できるのは大きなメリットです!
(・・・ということは、Electron
でも使いやすいですね)
逆にデメリットに感じたのは、何をするにもFirebase
の決めたルールを使わないといけませんが、この会社を所有しているGoogle
は頻繁に内容を変更しますし、ひどいときはサービスを急に終了するので、長期展望としては少し不安ではありますよね
とはいえ、技術的にはとても魅力的なので興味を持たれた方はぜひチャレンジしてみてくださいね。(なんなら専用のサーバーレス・サイトを作っておいても面白いかもしれません)
ではでは〜!