지난 글에서는 로그인을 위한 서버쪽 설정과 API를 작성해보았다.
<template>
<div class="wrapper">
<div id="login">
<div class="container">
<div class="row justify-content-center align-items-center">
<div class="col-sm-6">
<div class="card">
<h4 class="card-header">로그인</h4>
<div class="card-body">
<form data-toggle="validator" role="form" method="post" action="#">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Email</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i
class="fa fa-user"
aria-hidden="true"
/>
</span>
</div>
<input
type="text"
class="form-control"
placeholder="아이디(이메일)를 입력해주세요."
v-model="id"
/>
</div>
<div class="help-block with-errors text-danger"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Password</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">
<i
class="fa fa-lock"
aria-hidden="true"
/>
</span>
</div>
<input
type="password"
v-model="password"
placeholder="비밀번호를 입력해주세요."
class="form-control"
/>
</div>
<div class="help-block with-errors text-danger"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button
type="button"
class="btn btn-primary btn-lg btn-block"
@click="login()"
>
Login
</button>
</div>
</div>
</form>
<div class="form-group">
<div class="clear"></div>
<br>
<i class="fa fa-user fa-fw" />처음 방문하십니까?
<a href="/join">회원가입</a>
<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Login',
data () {
return {
id: "",
password: ""
}
},
methods: {
login() {
// 아이디와 패스워드 입력여부 확인
if (this.id && this.password) {
var id = this.id // 아이디
var password = this.password // 비밀번호
this.store.dispatch('login', {id, password}) // 로그인
} else {
alert("아이디 또는 비밀번호가 입력되지 않았습니다.")
return false
}
}
}
}
</script>
<style scoped>
#login {
margin-top: 150px;
}
</style>
위와 같이 로그인 화면을 구성하였다.
근데 우선 로그인 기능을 테스트하기전에 과정을 살펴보자.
위와 같은 과정을 지키기 위해 무언가 빠졌다. vuex의 store를 통해 서버 API에 로그인 요청할 수 있는 함수가 필요하다. 또 한 응답받은 데이터를 저장하여 사용할 수 있는 객체들을 따로 저장해야 한다. 그리고 vuex의 store에 저장한 데이터는 페이지 새로고침 시 사라지는데 이러면 습관적으로 새로고침시 다시 로그인을 해줘야한다. 그래서 추가 한것이 vuex-persistedstate 통해 새로고침과 같은 이슈를 해결했다.
vuex-persistedstate 는 store의 값에 변화가 생길 시 해당 값들을 localstorege에 저장 한 후 필요 시 localstorage를 통해 잃어버린 값을 되살려주는 기능이 있어서 유용하게 사용할 수 있다.
import axios from 'axios'
import { router } from '../router/index.js'
const state = {
token: null,
id: null,
name: null,
role: null,
email: null,
nickname: null
}
const getters = {
'token': state => state.token,
'id': state => state.id,
'email': state => state.email,
'nickname': state => state.nickname
}
const mutations = {
login (state, item) {
state.token = item.headers['accesstoken']
state.id = item.data['id']
state.role = item.data['role']
state.email = item.data['email']
state.nickname = item.data['nickname']
},
logout (state) {
state.token = null
state.id = null
state.role = null
state.email = null
state.nickname = null
}
}
const actions = {
login ({commit}, {id, password}) {
const params = {
"email": id,
"password": password
}
axios.post("http://localhost:8080/signin", JSON.stringify(params), {
headers: { 'content-type': 'application/json' }
}).then(res => {
commit('login', res)
router.push("/posts")
}).catch(e => {
console.log(e)
alert("로그인 요청에 문제가 발생했습니다.")
})
},
logout ({commit}) {
commit('logout')
}
}
export default {
state,
getters,
mutations,
actions
}
import { createStore } from 'vuex'
import createPersistedState from "vuex-persistedstate"
import modules from './modules.js'
const persistedState = createPersistedState({
paths: ['token', 'id', 'name', 'role', 'nickname']
})
export const store = createStore({
state: modules.state,
getters: modules.getters,
mutations: modules.mutations,
actions: modules.actions,
plugins: [persistedState]
})
이제 진짜 로그인을 해보자.
이렇게 응답객체에 대한 데이터를 확인해볼 수 있다.
사실 로그인말고 API 통신방식은 비즈니스 로직을 제외하고는 요청 ↔ 응답 이 패턴이라 크게 다를게 없어보인다.
이런식으로 회원가입도 만든상태이긴 한데 나중에 여유있으면 글로 다뤄보자!
전체 코드는 하단 링크를 통해 확인해보실 수 있습니다.
shinhyocheol/jpaPlatformAPI
shinhyocheol/vuePlatformView