#はじめに
個人開発をしようと思い、フロントにVue.js、バックエンドにGoを使うことに決めました。
よくある組み合わせですね。
制作物のテーマはTwitterを活用するものになる?予定なので、ログイン機能もTwitter認証を用いてログインする形式を採用することにしました。
認証にあたりfirebaseを用いると簡単に認証ができるということなので、今回活用してみることにしました。
結果として、「認証」だけなら簡単でした。(恐らく記事を探せば認証に関してはすぐ見つかると思います。)
ユーザー名とプロフ写真のURLの取得、ログイン状態の維持に関してはあまり記事がなく、3日間くらい悩みました。
同じように悩む人がいると思うので(私が雑魚なだけ?)、備忘録兼同じことをやりたい人の為に、ここに載せておきます。
#準備するもの
firebaseからTwitter認証できるように、TwitterAPIを入力する項目があります。
そのため、あらかじめTwitterAPIを取得していないといけません。
API取得に関してはここでは紹介いたしませんので、別途個人で取得をお願いいたします。
またVue
xとvue-router
も使うので、入れていない人は追加をお願いします。
#実際の画面#
①signinボタンをクリックする
②Twitter連携のポップアップが表示される
③連携アプリを認証し、ホーム画面へ
Twitterのユーザー名・プロフィール写真も表示される
#Twitter認証方法
##ログイン
##
下記の通り、Signinボタンを押すとクリックイベントに応じて、signinメソッドが実行されます。
signinメソッドのfunction()
以降がログインに関わる部分です。
firebaseのDocsにあるTwitter認証のリファレンスとこちらの記事を参考に、ここの処理を作成しました。
今回はユーザー名・プロフ写真が欲しいので、ログインユーザーのユーザー名とプロフ写真のURLを取得し、格納するcurrentUser
プロパティを用意します。
currentUser
の情報は全画面共通で使いたい(例えばQiitaは、どの画面に飛んでも自分のTwitterのプロフ写真が載ってますよね?)ので、store.js
にcommitして送ります。
後半のエラー処理に関してはよく分からなかったので、とりあえず書いただけです。あまり参考にしないで下さい…。
<template>
<div class="signin">
<h2>Sign in</h2>
<button @click="signin">Signin</button>
</div>
</template>
<script>
import firebase from "firebase";
export default {
name: "Signin",
methods: {
signin: function() {
var provider = new firebase.auth.TwitterAuthProvider();
firebase
.auth()
.signInWithPopup(provider)
.then(
result => {
var token = result.credential.token;
var secret = result.credential.secret;
var user = result.user;
if (user) {
const currentUser = { // ←こいつ必要
displayName: user.displayName,
photoURL: user.photoURL
};
this.$store.commit("setUser", currentUser); // currentUserをstore.jsに渡す
this.$router.push("/");
} else {
alert("有効なアカウントではありません");
}
},
err => {
alert(err.message);
}
);
}
}
};
</script>
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
// strictモードは本番環境ではfalseにすること
strict: true,
state: {
user: {
displayName: "",
photoURL: ""
}
},
getters: {
getURL(state) { // ←こいつは後半に使う処理なので覚えておいてください
return state.user.photoURL
}
},
mutations: {
setUser(state, currentUser) { // commitされるとmutationsのsetUserが実行される
state.user.displayName = currentUser.displayName // ここでユーザー名をstateにセットできる
state.user.photoURL = currentUser.photoURL // 同様に写真URLをセットする
}
},
actions: {
}
})
##ログイン状態の維持
##
ログイン状態の維持にはfirebase.auth().onAuthStateChanged()
を使います。
ここら辺に関してはまだ詳しくないので、うまく説明することができないのです。すみません。
ただ見てもらえれば分かる通り、ログイン状態であるかどうかの判別をここでしています。
ログイン状態であればstore.jsに、上記同様currentUserを引数にしてcommitします。
維持というよりは更新と言った方が正確かもしれません。
画面が変わるごとに最新の状態に更新しているの、最新の状態に保つ=維持ともいえるということなのでしょうね。
// 認証状態を確認
// Vueのインスタンス化
const app = () => {
firebase.auth().onAuthStateChanged(currentUser => {
if (currentUser) {
store.commit("setUser", currentUser)
} else {
store.commit("setUser", null)
}
}),
/* eslint-disable */
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
}
// 関数実行
app()
##ユーザー名・プロフ写真の取得
##
他にも色々なものが下記のコードに入っているのですが、見づらさが増すので必要な部分だけ記載しております。
このコンポーネントで行っていることはいたってシンプルです。
store.js
のstate
の値を持ってきているだけです。
今回は勉強もかねてmapState
とmapGetters
を使用しています。
注意する点というか私がハマった点は、
src属性にどうやってstore.jsのuserプロパティのphotoURLを入れるのか
というところです。(Vue.js初心者なのでまったくわかりませんでした...)
<template>
<div class="hello">
<h1>Hello</h1>
<p>{{ user.displayName }}</p> <!--userのdisplayName(あなたのTwitterのユーザー名)を表示します-->
<img :src="url" /> <!--mapGettersのurl(←名前は何でもいい)をv-bindしたsrc属性に記述してください-->
<h2>Essential Links</h2>
</div>
</template>
<script>
import firebase from "firebase";
import { mapState, mapGetters } from "vuex";
export default {
name: "HelloWorld",
data() {
return {
},
computed: {
...mapState({
user: state => state.user // stateのuserプロパティを取得する処理にuserという別名を与える
}),
...mapGetters({ url: "getURL" }) // mapGettersのgetURLに別名を与える
}
};
</script>
まずVueのルールで````のような記述をすることはできません。
``のような書き方をしたいところですが、
data``に値がないのでこれもエラーとなります。
結果としてはgetters
経由で取得することができたので、今回はこのように処理することが正解なのかもしれないですね。
#終わりに#
一連の処理については以上となります。
私自身、まだエンジニア歴半年になるかならないかぐらいの素人なので、今回の投稿内容も正確さに欠ける点が多いと思います。
参考の参考程度にしていただくだけでも幸いです。