[Vue.js] 토큰 기반 인증(#3. 사용자 등록)

하수도키

·

2020. 8. 30. 15:23

728x90
반응형
SMALL

 

2020/10/31 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증 (#7. 자동 로그인)

2020/10/31 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증 catch 사용 (#6. 에러 처리)

2020/10/30 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#5. 유저 로그아웃)

2020/10/28 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#4. 유저 로그인)

2020/08/30 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#3. 사용자 등록)

2020/07/27 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#2. 인증을 위한 프로젝트 구조 살피기)

2020/07/24 - [개발일기/Vue.js] - [Vue.js] 토큰 기반 인증(#1. 인증소개)

[Vue.js] 토큰 기반 인증(#3. 사용자 등록)

개요

  • 이제 구조도 살펴봤고 사용자 등록을 해보자.
  • 현재 상태는 로그인하지 않는 사용자들(권한이 없는 사용자들)도 dashboard 에 접근이 가능한데 로그인한 사용자들만 접근이 가능하게 변경해보자.
  • 기존 server.js 파일에서 dashboard API를 부분을 아래와 같이 코드를 변경한다.
/server.js
app.get('/dashboard', verifyToken, (req, res) => { // vertifyToken = 미들웨어 req.token을 지정
  jwt.verify(req.token, 'the_secret_key', err => { // token 확인하기
 	 if (err) { // 만약 토큰이 이상하면 401 에러
		res.sendStatus(401)
	 } else { // 토큰이 정상이면 아래 데이터 응답
		res.json({
		   events: events
		})
	 }
  })
})
  • 현재 server.js는 가상 인증 서버를 express.js로 만들었다.(token도 설정되어 있는 상태)
  • http://localhost:8080/dashboard 이렇게 접근 하면 아래와 같은 화면처럼 에러가 발생한다.

  • /dashboard 에러 발생
    Failed to load resource: the server responded with a status of 401 (Unauthorized)

  • 즉, 권한이 없다라고 에러가 나온다.

  • 사용자가 가입(Register)완료가 될때, 그때 토큰도 같이 발행한다. 이 토큰은 권한이 필요한 데이터에 접근할때 이걸로 체크한다. /dashboard API 호출시에 토큰이 같이 보내지고 이 토큰이 정상이면 데이터를 반환하고 비정상이면 에러를 발생시킨다.

  • 이제 우리가 해야 될 리스트는 아래와 같다.

    1. RegisterUser.vue 컴포넌트 만들기
    2. 이 컴포넌트는 name, email, password를 사용자들로부터 받고, Vuex를 사용해 서버의 /register를 호출 한다.
    3. Vuex store에 추가
    4. 서버의 /register로 부터 받은 응답을 Mutation에 저장하고 사용자를 등록한 Action이 필요하다. 그리고 axios header에 토큰 추가하기.
    5. RegisterUser 라우터 추가

RegisterUser 컴포넌트 만들기

  • 아래 이미지 같은 Form 을 만들어 보자.

  • form을 통해 name, email, password를 얻는다.
  • 따라서 RegisterUser 컴포넌트 data에 추가
// src/views/RegisterUser.vue
data () {
  return {
  name: '',
  email: '',
  password: ''
  }
},
  • input을 각각 만들고 v-modeldata와 바인딩한다.
  • 그리고 마지막에 form 데이터를 보낼 버튼도 만든다.
// src/views/RegisterUser.vue
<template>
  <div>
  <form @submit.prevent="register">
 <label for="name">
   Name:
 </label>
 <input v-model="name" type="text" name="name" value>

 <label for="email">
   Email:
 </label>
 <input v-model="email" type="email" name="email" value>

 <label for="password">
   Password:
 </label>
 <input v-model="password" type="password" name value>

 <button type="submit" name="button">
   Register
 </button>
  </form>
  </div>
</template>
  • 이제 채워진 user databackend server /register API로자격증명(credentials)으로 보내야 한다.
  • Register 버튼을 누르면 form 태그안에 type='submit' 버튼으로 자동으로 form submit 이벤트가 발생한다. 기본 이벤트를 방지하려면~?
    • form태그에 @submit.prevent="register"추가해 기본 form 이벤트를 방지하고 reigster 메서드를 실행하게 한다.
  • register 메서드는 사용자 정보를 Vuex Action으로 dispatch한다.
// src/views/RegisterUser.vue
methods: {
  register () {
  this.$store
 .dispatch('register', {
   name: this.name,
   email: this.email,
   password: this.password
 })
  }
}

Vuex 설정하기

  • 이제 register Action을 작성하기전에 올바른 데이터가 넘어갔는지 확인해보자 (name,email,password)
  • register Action은 API 호출하므로 axios 를 불러와야 한다.
// src/store.js
import axios from 'axios' // axios 불러오기
...
export default new Vuex.Store({
  state: {},
  mutations: {},
  actions: {
  register ({ commit }, credentials) {
 return axios
   .post('//localhost:3000/register', credentials)
   .then(({ data }) => {
  console.log('user data is', data)
  commit('SET_USER_DATA', data)
   })
  }
  }
})
  • register axios post 요청은 server register API를 호출한다.
  • API 호출할때 credentials(name, email, password)payload로 함께 넘긴다.
    • payloadRegister 컴포넌트에서 보낸것이다.
  • server.js에서 받은 유저 정보를 user.json 파일에 저장하고 JWT tokenname,email 를 포함한 객체를 반환한다.
  • console.log('user data is', data) 의 결과값은 아래와 같다.
user data is 
{token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7I…MxN30.-Zi1H3YCXKMecnxp13oIDH-hlPahhDzj2zkzL4fMoks", email: "beatdance@naver.com", name: "lee"}
email: "beatdance@naver.com"
name: "lee"
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7Im5hbWUiOiJsZWUiLCJlbWFpbCI6ImJlYXRkYW5jZUBuYXZlci5jb20iLCJwYXNzd29yZCI6ImFzZGZhc2RmIn0sImlhdCI6MTU1ODQyODMxN30.-Zi1H3YCXKMecnxp13oIDH-hlPahhDzj2zkzL4fMoks"
__proto__: Object
  • 아직 register 라우트가 존재하지 않아서 테스트가 불가하니 빨리 만들어보자.

Register 라우트 추가

  • RegisterUser 컴포넌트를 import 하고 라우트를 추가한다.
// src/router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import Dashboard from './views/Dashboard.vue'
import RegisterUser from './views/RegisterUser.vue'

Vue.use(Router)
const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
  {
 path: '/',
 name: 'home',
 component: Home
  },
  {
 path: '/dashboard',
 name: 'dashboard',
 component: Dashboard
  },
  {
 path: '/register',
 name: 'register',
 component: RegisterUser
  }
  ]
})

서버에서 받은 응답 저장하기

  • 가입 후 응답 받은 값 저장하기
    • Vuex State에 저장
    • LocalStorage에 저장
    • Axios Header에 토큰 추가
  • 위 3가지 단계들은 Mutatation SET_USER_DATA에서 작업
// store.js
state: {
  user: null
},
mutations :{
  SET_USER_DATA (state, userData) {
 state.user = userData
 localStorage.setItem('user', JSON.stringify(userData))
  }
}
  • user state를 추가
  • localStorage는 문자열만 저장 가능하니 JSON.stringify로 자바스크립트 객체를 JSON 문자로 변경한다
  • 마지막으로 userData의 토큰을 Axios Header에 추가한다.
  • 추가하면 API을 호출할때 토큰이 같이 포함되어 요청 된다. 서버에서 토큰을 key 처럼 사용해 /dashboard API에서 체크하여 권한을 얻는다.
import axios from 'axios' 
...
mutations: {
SET_USER_DATA (state, userData) {
  state.user = userData
  localStorage.setItem('user', JSON.stringify(userData))
 axios.defaults.headers.common['Authorization'] = `Bearer ${
 userData.token
  }`  
},
  • 위 코드는 Axios instance Authorization HeaderJWT Token을 포함시킨다.
  • Bearer는 인증의 사용되는 타입이라고 알아두자. 자세한건 https://developers.google.com/gmail/markup/actions/verifying-bearer-tokens 여기 참조
  • 우리는 Axios에게 JWT Token을 줘서 서버가 /dashboard 종점에서 잠금을 풀 수 있다.
  • localStorage 저장된 데이터로 새로고침될때 상태값을 재설정할 수 있다.
  • 위와 같이 작업하면 이제 dashboard 에 접근이 가능하다.

Dashboard로 리다이렉트

  • 현재 사용자가 등록버튼을 누르면 아무런 페이지 변화가 없다.
  • 등록 버튼을 누르고 성공적으로 완료되면 dashboard로 리다이렉트하는 코드이다.
methods: {
  register () {
  this.$store
 .dispatch('register', {
   name: this.name,
   email: this.email,
   password: this.password
 })
 .then(() => {
   this.$router.push({ name: 'dashboard' })
 })
  }
}

브라우져에서 테스트

  • 브라우저을 열고 등록, 로그인하면 dashboard가 보인다.
  • 개발자 도구를 열고 network tab으로 가면 register와 dashboard 호출을 볼 수 있는데 dashboard를 보면 토큰이 Authorization header 추가된걸 볼 수 있다.
  • 토큰을 보면 중간 중간 .으로 구분되어 3개의 파트로 나눠지는걸 볼 수 있다.

결론

  • 지금까지 유져 등록하고 토큰 생성하고 토큰으로 dashboard를 불러오는것 까지 했다.
  • 다음장에서는 Login에 대해 포스팅해보겠다.
  • 정리가 잘 안되서 이번 최종소스는 여기를 참고해주시면 됩니다! >_<
728x90
반응형
LIST