ログインしたいなーっと思ったのでやってみた。
express-sessionをインストールする
$ npm install express-session --save
#ストアを作る
認証(login)してユーザ情報をストアに保存する。
store/auth.js
export const state = () => ({
authUser: null
})
export const mutations = {
SET_USER(state, authUser) {
state.authUser = authUser
}
}
export const actions = {
async login({ commit }, { username, password }) {
try {
const { data } = await this.$axios.post('/auth/login', { username, password })
commit('auth/SET_USER', data)
} catch(error) {
if (error.response && error.response.status === 401) {
throw new Error(error.response.data.error)
}
throw error
}
},
async logout({ commit }) {
await this.$axios.post('/auth/logout')
commit('auth/SET_USER', null)
}
}
セッションに保存しているユーザ情報をストアに保存する。
nuxtServerInitアクション
store/index.js
export const actions = {
nuxtServerInit({ commit }, { req }) {
if (req.session && req.session.authUser) {
commit('auth/SET_USER', req.session.authUser)
}
}
}
apiを作る
sessionの設定を記述する。
nuxt.config.js
import bodyParser from 'body-parser'
import session from 'express-session'
export default {
serverMiddleware: [
bodyParser.json(),
session({
secret: 'super-secret-key',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}),
'~/api/auth.js'
]
}
ユーザ、パスワードを認証してユーザ情報をセッションに保存する。
api/auth.js
const express = require('express')
const app = express()
app.post('/login', (req, res) => {
const username = req.body.username
const password = req.body.password
if (username === 'demo' && password === 'demo') {
req.session.authUser = { username }
return res.json({ username })
}
res.status(401).json({ error: '認証失敗' })
})
app.post('/logout', (req, res) => {
delete req.session.authUser
res.json({ ok: true })
})
module.exports = {
path: '/api/auth',
handler: app
}
middlewareを作る
ストアにユーザ情報が保存されていなければログインページにリダイレクトする。
middlewareプロパティ
middleware/auth.js
export default ({ store, redirect }) => {
if (!store.state.auth.authUser) {
return redirect('/login')
}
}
middlewareプロパティにauth
を設定する。
pages/index.vue
<template>
<div>
ログイン成功 <button @click="logout">ログアウト</button>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
middleware: 'auth'
methods: {
...mapActions('auth', { postLogout: 'logout' }),
async logout() {
await this.postLogout()
this.$router.push('/login')
}
}
}
</script>
ログインページを作る
pages/login.vue
<template>
<div>
<form @submit.prevent="login" :class="{ error: isError }">
<input v-model="username" type="text" name="username" placeholder="ユーザ名" />
<input v-model="password" type="password" name="password" placeholder="パスワード" />
<button type="submit">ログイン</button>
</form>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data: () => ({
username: '',
password: '',
isError: false
}),
methods: {
...mapActions('auth', { postLogin: 'login' }),
async login() {
try {
await this.postLogin({ username: this.username, password: this.password })
this.isError = false
this.$router.push('/')
} catch(e) {
this.isError = true
}
}
}
}
</script>
<style lang="scss" scoped>
.error {
input {
background: salmon;
border-color: red;
}
}
</style>
その他
他にも外部認証API(JWT)なるものがあるのか。
後でやってみようかな?気になるし。。。