web/back + front

vue+flask 시작 로그인 구현 4. vue에서 flask의 값 받아서 관리하기. vuex

qkqhxla1 2018. 7. 20. 17:10

바로 전 글에서 flask에는 jwt라는걸 이용해 인증을 한다고 했다. 그리고 파이썬으로 테스트까지 완료하였다. 어떻게 동작하는지 확인하였으니 이젠 vue에서 jwt인증요청을 보내고 access_token을 받아서 저장까지 구현해봤다.

뷰에서는 어떻게 이러한것들을 저장할까. 찾다 발견한게 vuex이다. 아래는 vuex튜토리얼이다.


https://vuex.vuejs.org/kr/ 

이해가 잘 안가서 5번은 읽어본것 같다.


vuex를 기반으로 /mystore안에 store를 만든다. (다른분이 짠걸 가져와서 변형했다..)


/mystore/index.js

import Vue from 'vue'
import Vuex from 'vuex'

const LOGIN = 'LOGIN'
const LOGIN_SUCCESS = 'LOGIN_SUCCESS'

Vue.use(Vuex)

const state = {
  isLoggedIn: !!localStorage.getItem('access_token'),
  token: localStorage.getItem('access_token'),
  refresh_token: localStorage.getItem('refresh_token')
}

const mutations = {
  [LOGIN] (state) {
    state.pending = true
  },
  [LOGIN_SUCCESS] (state) {
    state.isLoggedIn = true
    state.pending = false
  }
}

const actions = {
  login ({ commit }, creds) {
    // console.log(creds)
    commit(LOGIN) // show spinner
    return new Promise(resolve => {
      setTimeout(() => {
        commit(LOGIN_SUCCESS)
        localStorage.setItem('access_token', creds.token)
        localStorage.setItem('user_name', creds.user_name)
        localStorage.setItem('refresh_token', creds.refresh_token)
        resolve()
      }, 1000)
    })
  }
}

export default new Vuex.Store({
  state,
  mutations,
  actions
})

vuex state의 mutation, action개념을 이해하는데는 한글보다 영어 튜토리얼이 이해가 더 편했다.

mutation이 변이라고 해석이 되는데 뭔가 매치가 안되서 해맸다.

https://vuex.vuejs.org/guide/state.html 영어 튜토리얼.

https://stackoverflow.com/questions/39299042/vuex-action-vs-mutations 참고.


actions의 login함수를 호출하게 되면 commit로 mutations의 LOGIN, LOGIN_SUCCESS을 실행해서 state의 상태를 변경한다. 흐름은 맨 마지막에 한번 더 적겠다. 그리고 localStorage에 access_token, user_name, refresh_token을 저장한다. localStorage가 어디있는지 몰랐는데 크롬 개발자도구로 확인이 가능하다.(맨 마지막에 스샷 첨부)


그리고 store의 결과를 가져와 사용하기 위해 return시 new Promise로 리턴을 했다.

참조 : https://stackoverflow.com/questions/42195971/how-can-i-get-response-of-this-store-dispatch-on-the-vue-js-2


선언한 store을 사용하기 위해 main.js에서 import해주었다.

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
import BootstrapVue from 'bootstrap-vue/dist/bootstrap-vue.esm'
import axios from 'axios'
import store from './mystore'
import 'es6-promise/auto'

import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.use(BootstrapVue)
Vue.config.productionTip = false
Vue.prototype.$axios = axios

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>',
  render: h => h(App)
})

import  store from './mystore'

new Vue({

...

store, //추가해줘야 사용할수 있다.

....

})


이제다시 Login.vue를 보자. http://qkqhxla1.tistory.com/966?category=757287 에서의 Login.vue는 뼈대만 있다. 그냥 post로 호출하기만하고 response를 출력해 보았는데

methods: {
  login: function () {
  let LdapInfo = {
      ldap_id: this.credentials.username,
      ldap_pw: this.credentials.password
    }
    this.$axios.post(`/api/login`, LdapInfo).then((response) => {
      alert(response.data.code)
    })
  }
}

이제 제대로 된 데이터를 서버에서 주는만큼 받아서 쓰면 된다.

methods: {
    login: function () {
      let LdapInfo = {
        ldap_id: this.credentials.username,
        ldap_pw: this.credentials.password
      }
      this.$axios.post(`/api/login`, LdapInfo).then((response) => {
        alert(response.data['user_name'] + ' has logged in!')
        this.$store.dispatch('login', {
          user_name: response.data['user_name'],
          token: response.data['access_token'],
          refresh_token: response.data['refresh_token']
        })
      }).catch((error) => {
        alert('error : ' + error.response.data['msg'])
      })
    }
  }

post로 데이터를 날리고 this.$store.dispatch로 login이라는 액션을 실행한다. 

https://vuex.vuejs.org/guide/actions.html


그러니까 제대로 로그인 정보를 입력하면 ajax로 /api/login페이지로 login정보를 보내고, 이 정보는 /api/login에 매핑된 python_src의 login.py에서 받아서 처리하고 유효한 정보면 store로 login이라는 액션을 실행한다. login액션은 아까 위에서 정의한 /mystore에 있는 actions의 login이다.


제대로 구현이 되었으면 크롬 개발자도구의 Application탭에 아래처럼 보인다.