Spring + Vue 로그인(2)

shinhyocheol·2021년 7월 15일
0

로그인 기능(1)

지난 글에서는 로그인을 위한 서버쪽 설정과 API를 작성해보았다.

Login.vue

<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>

위와 같이 로그인 화면을 구성하였다.

근데 우선 로그인 기능을 테스트하기전에 과정을 살펴보자.

  1. 아이디(이메일), 패스워드 입력 후 로그인 버튼 클릭
  2. 클라이언트는 사용자가 입력한 정보를 vuex의 store(Vuex는 상태관리 패턴 + 라이브러리)를 통해 로그인 API에 전달한다.
  3. API 에서는 요청 시 넘겨받은 데이터를 가지고 존재하는 회원인지, 존재한다면 비밀번호가 일치하는지 검사한다.
  4. 해당 과정을 통과한다면 서버는 사용자 정보와 함께 해당 사용자에 대한 인증값(토큰)을 발급한다.
  5. 사용자 정보와 인증토큰을 클라이언트에게 응답한다.
  6. 클라이언트는 토큰과 사용자 정보를 정상적으로 응답 받았다면 해당 데이터들을 store를 통해 클라이언트에서 저장한 후 약속된 화면이동을 실행한다.

위와 같은 과정을 지키기 위해 무언가 빠졌다. vuex의 store를 통해 서버 API에 로그인 요청할 수 있는 함수가 필요하다. 또 한 응답받은 데이터를 저장하여 사용할 수 있는 객체들을 따로 저장해야 한다. 그리고 vuex의 store에 저장한 데이터는 페이지 새로고침 시 사라지는데 이러면 습관적으로 새로고침시 다시 로그인을 해줘야한다. 그래서 추가 한것이 vuex-persistedstate 통해 새로고침과 같은 이슈를 해결했다.

vuex-persistedstate 는 store의 값에 변화가 생길 시 해당 값들을 localstorege에 저장 한 후 필요 시 localstorage를 통해 잃어버린 값을 되살려주는 기능이 있어서 유용하게 사용할 수 있다.

src/store/module.js

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
}

store/index.js

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]
})

이제 진짜 로그인을 해보자.

response body

이렇게 응답객체에 대한 데이터를 확인해볼 수 있다.

사실 로그인말고 API 통신방식은 비즈니스 로직을 제외하고는 요청 ↔ 응답 이 패턴이라 크게 다를게 없어보인다.

이런식으로 회원가입도 만든상태이긴 한데 나중에 여유있으면 글로 다뤄보자!

전체 코드는 하단 링크를 통해 확인해보실 수 있습니다.
shinhyocheol/jpaPlatformAPI
shinhyocheol/vuePlatformView

profile
놀고싶다

0개의 댓글