nuxt authentication flow

[NUXT] Nuxt Middleware 로그인 처리하기

로그인 > 토큰 받음 > 토큰을 쿠키와 vuex store에 저장

일단 지금은 api 연결이 되어 있지 않으니 임시 더미 토큰을 만들어 놓기로 한다. 로그인 화면에서 로그인 버튼을 눌렀을 때, 스토어에서 서버로부터 토큰을 받아 스토어에 저장시키는 액션을 디스패치한다.

// store/index.js : 뷰엑스 스토어

import JSCookie from 'js-cookie'  // 쿠키에 값을 넣어주기 위해 사용
import cookie from 'cookie'  // 쿠키의 데이터를 파싱해서 읽을 수 있는 JSON으로 받기 위해

export const state = () => ({
  posts: [],
  keyword: '',
  token: '',
})

...

export const mutations = {
  ...
  setStoreToken(state, token) {
    state.token = token
  },
}

...

export const actions = {
	nuxtServerInit({ dispatch }, { req }) {
    let token = null
    if (req.headers.cookie) {
      const parsed = cookie.parse(req.headers.cookie)
      try {
        token = parsed.token
      } catch (err) {
        console.error(err)
      }
    }
    dispatch(SET_LOGIN_TOKEN_TO_COOKIE, token)
  },
	[GET_TOKEN_FROM_SERVER]({ dispatch }) {
    // 토큰을 서버에서부터 가져와 로그인하는 로직
    const res = { token: '123456789' }
    if (res.token) {
      dispatch(SET_LOGIN_TOKEN_TO_COOKIE, res.token)
    }
  },
  [SET_LOGIN_TOKEN_TO_COOKIE]({ commit }, token) {
    // store와 쿠키에 토큰을 넣는 로직
    commit('setStoreToken', token)
    JSCookie.set('token', token)
  },
...
}

새로고침 시 스토어의 토큰이 사라지는 문제 해결 → 쿠키를 사용하기

스토어가 새로고침하면서 데이터가 없어지는 문제를 해결하기 위해 쿠키 헤더에 토큰을 저장하여 사용한다.
> 토큰을 쿠키에 저장하고, 렌더링 시에 스토어의 토큰 값에 쿠키의 토큰을 다시 넣어준다 
> nuxtServerInit을 사용해, 페이지가 생성되기 전에 store에서 해당 작업을 수행해준다.

여기서 중요한 게 nuxtServerInit인데, 이 친구 안에서 클라이언트가 서버로 보내는 요청의 헤더에 쿠키가 있는지를 파악하고, 있다면 해당 쿠키를 파싱해서 스토어에 넣어주는 역할을 담당한다. 이 로직이 필요한 이유는, 만약 새로고침을 실시할 경우 스토어의 값들이 초기화되는 문제를 해결하기 위해서이다.

nuxtServerInit이란 넉스트 라이프사이클 훅 중 맨 처음으로 실행되는 친구로, 페이지에 진입하기 전 스토어가 생성되는 시점에, 서버 사이드에서 실행되는 스토어의 액션 속성이다. 따라서 스토어에 필요한 데이터를 미리 설정해 놓거나 서버에서만 접근할 수 있는 데이터를 다룰 때 사용할 수 있다.

따라서 nuxtServerInit을 통해 각 페이지에 진입하기 전 미리 다시 스토어의 토큰 값을 쿠키에 받아서 다시 세팅해줄 수 있다.

nuxtServerInit은 두 개의 context를 인자로 받는다. 첫 번째로 store context, 두 번째로는 nuxt context이다. nuxt context에서 클라이언트가 넉스트의 내부 node.js 서버에 보내고 받는 요청req과 응답res를 볼 수 있다. 클라이언트가 initial request를 서버에 보내고, 서버는 이에 맞는 HTML을 브라우저에게 보내준다. 이 결과가 nuxt context의 res, req를 통해 접근이 되고, 이것을 서버 사이드에서도 확인할 수 있는 것이다.

이에 반해 SET_LOGIN_TOKEN_TO_COOKIE 디스패치의 경우 클라이언트 사이드 로직이기 때문에 쿠키에 직접 접근이 가능해, JSCookie를 사용하여 쿠키를 만질 수 있다.

서버 사이드와 클라이언트 사이드 양쪽에서 쿠키를 동시에 사용할 수 있는 cookie-universal-nuxt

그런데 넉스트에서 신박하게 서버와 클라이언트 모두에서 쿠키를 사용할 수 있도록 해 주는 플러그인이 있어 사용했다. 이를 사용하면 nuxtServerInit에서도 nuxt context를 사용하지 않아도 간편하게 쿠키에 접근할 수 있다.

// nuxt.config.js에서 쿠키의 alias를 설정해주고

modules: [
    ...
    ['cookie-universal-nuxt', { alias: 'cookiz' }],
  ],

이를 사용한다.