Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #5 ログイン・ログアウトの実装

←[Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #4 サインアップページの作成](https://qiita.com/rf_p/items/c1162fc121d6a4ef53e6)

# ログアウト機能の実装

先にログアウトを作ります。

```diff:layouts/default.vue
...
       <v-btn
         v-if="logged_in"
         icon
+        @click="logOut"
       >
         <v-icon>mdi-logout</v-icon>
       </v-btn>
...
export default {
...
           this.$store.commit('setAuth', {})
         })
     }
+  },
+  methods: {
+    logOut () {
+      this.$store.dispatch('logOut')
+    }
   }
 }
 </script>
```

```diff:store/index.js
...
 export const actions = {
   async signUp (_c, user) {
     return await this.$axios.$post('/v1/auth', user)
+  },
+  async logOut ({ commit }) {
+    await this.$axios.$delete('/v1/auth/sign_out')
+    commit('setUser', null)
+    commit('setAuth', {})
+
+    this.$router.push('/')
   }
 }
```

`v1/auth/sign_out`することでバックエンドでログアウトとします。
そしてフロントエンド側もstoreから削除し（同時にlocalStorageもクリアされます）、トップページに飛ばします。

# ログイン機能の実装

```powershell
$ touch pages/log_in.vue
```

```vue:pages/log_in.vue
<template>
  <v-app id="inspire">
    <v-main>
      <v-container
        class="fill-height"
        fluid
      >
        <v-row
          align="center"
          justify="center"
        >
          <v-col
            cols="12"
            sm="8"
            md="4"
          >
            <form @submit.prevent="logIn">
              <v-card class="elevation-12">
                <v-toolbar
                  color="primary"
                  dark
                  flat
                >
                  <v-toolbar-title>LogIn form</v-toolbar-title>
                </v-toolbar>
                <v-card-text>
                  <ul v-if="errors">
                    <li v-for="(message, i) in errors" :key="i">
                      {{ message }}
                    </li>
                  </ul>
                  <v-text-field
                    id="email"
                    v-model="email"
                    label="email"
                    name="email"
                    prepend-icon="mdi-email"
                    type="email"
                  />

                  <v-text-field
                    id="password"
                    v-model="password"
                    label="Password"
                    name="password"
                    prepend-icon="mdi-lock"
                    type="password"
                  />
                </v-card-text>
                <v-card-actions>
                  <v-spacer />
                  <v-btn color="primary" type="submit">
                    ログイン
                  </v-btn>
                </v-card-actions>
              </v-card>
            </form>
          </v-col>
        </v-row>
      </v-container>
    </v-main>
  </v-app>
</template>

<script>
export default {
  data () {
    return {
      email: '',
      password: '',
      errors: []
    }
  },
  methods: {
    async logIn () {
      try {
        const data = await this.$store.dispatch('logIn', {
          email: this.email,
          password: this.password
        })
        this.$store.commit('setUser', data.data)
        this.$router.push('/')
      } catch (e) {
        this.errors = e.data.errors
      }
    }
  }
}
</script>

```

```diff:store/index.js
...
export const actions = {
...
  async logOut ({ commit }) {
    await this.$axios.$delete('/v1/auth/sign_out')
    commit('setUser', null)
    commit('setAuth', {})

    this.$router.push('/')
+ },
+ async logIn (_c, user) {
+   return await this.$axios.$post('/v1/auth/sign_in', user)
  }
```

```diff:layouts/default.vue
...
         <v-icon>mdi-account-plus</v-icon>
       </v-btn>
+      <v-btn
+        v-if="!logged_in"
+        icon
+        to="/log_in"
+        nuxt
+      >
+        <v-icon>mdi-login</v-icon>
+      </v-btn>
     </v-app-bar>
...
```

ほとんどsignUpのコピペでいけます。

未ログインだと以下のようになります。
![未ログイン中](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/4245c04e-c1e4-cf34-53dc-37e479bf888b.png)

そしてログイン中だと以下のようになります。
![ログイン中.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199678/47af4e9a-805b-781a-7094-a77687271d8d.png)

これでログイン周りの必要最低限の機能は揃いましたね。

次回は連載最終回。記事の投稿・削除を行います。

# 続き

→[Nuxt.jsで認証認可入り掲示板APIのフロントエンド部分を構築する #6 記事投稿フォームの作成](https://qiita.com/rf_p/items/496a5eb49289a90633e2)
【[連載目次へ](https://qiita.com/rf_p/items/0277ae96c5de433b4849#%E7%9B%AE%E6%AC%A1)】