Vue + AWS Amplify でFacebook認証する

Amplifyを使ってFacebook認証を設定します。 公式のドキュメントに従って進めていきます。

Amplify Authentication

amplifyの初期化については省略。 amplify add auth コマンドを実行すると以下のように認証するプロバイダについて聞かれるのでfacebookを選択。

Do you want to use the default authentication and security configuration? 
  Default configuration 
❯ Default configuration with Social Provider (Federation) 
  Manual configuration 
  I want to learn more.

このような感じになります。 サインイン・サインアウト時のコールバックURLはいずれもlocalhost:8080を指定。 この値は複数設定できるので開発用・本番用それぞれのURLを設定することができますね。

$ amplify add auth
Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito.

 Do you want to use the default authentication and security configuration? Default configuration with Social Provider (Federation)
 Warning: you will not be able to edit these selections.
 How do you want users to be able to sign in? Email
 Do you want to configure advanced settings? No, I am done.
 What domain name prefix you want us to create for you? amplifyauthfacebook8xxxxxxx-8xxxxxxx
 Enter your redirect signin URI: http://localhost:8080/
? Do you want to add another redirect signin URI No
 Enter your redirect signout URI: http://localhost:8080/
? Do you want to add another redirect signout URI No
 Select the social providers you want to configure for your user pool: Facebook

 You've opted to allow users to authenticate via Facebook.  If you haven't already, you'll need to go to https://developers.facebook.com and create an App ID.

 Enter your Facebook App ID for your OAuth flow:  9xxxxxxxxxxxxxx
 Enter your Facebook App Secret for your OAuth flow:  953a071121d811c668d9d1ee006f5bed

Successfully added resource amplifyauthfacebook8xxxxxxx locally

VueアプリケーションにAmplifyのプラグインを組み込み。

npm install --save aws-amplify aws-amplify-vue

とりあえず認証ができればいいので、それ用のコンポーネントを作ってやります。

src/components/AuthPage.vue

<template>
  <div>
    <button @click="signin">SignIn with Facebook</button>
    <button @click="signout">SignOut</button>

    <div v-if="isAuthenticated">
      you signined with
      <strong>{{ userEmail }}</strong
      >.
    </div>
  </div>
</template>

<script lang="ts">
import Amplify, { Auth } from "aws-amplify";

export default {
  name: "auth",

  async created() {
    Auth.currentAuthenticatedUser()
      .then(user => {
        this.$store.commit("setUser", { user });
      })
      .catch(error => {
        console.warn(error);
      });
  },

  computed: {
    isAuthenticated() {
      return this.$store.state.user !== null;
    },
    userEmail() {
      if (!this.isAuthenticated) {
        return "";
      }

      return this.$store.state.user.attributes.email;
    }
  },

  methods: {
    signin() {
      Auth.federatedSignIn({ provider: "Facebook" });
    },
    signout() {
      Auth.signOut()
        .then(data => {
          this.$store.commit("removeUser");
        })
        .catch(err => console.log(err));
    }
  }
};
</script>

src/views/Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <AuthPage></AuthPage>
  </div>
</template>

<script>
import AuthPage from "@/components/AuthPage.vue";
import { Auth } from "aws-amplify";

export default {
  name: "home",
  components: {
    AuthPage
  }
};
</script>

gyazo.com

これでfacebookによるログインができます、、、と言いつつ一つ解決できていない問題があって、 ログインしてリダイレクトされた戻ってきたときにAuth.currentAuthenticatedUser()で認証したユーザーが取得できない。 一度リロードすれば取れるのだけど。。

ということで引き続き調べます。 今回書いたコードはここに置きました。

github.com