[Vue.js] 토큰 기반 인증(#4. 유저 로그인)
하수도키
·2020. 10. 28. 23:42
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] 토큰 기반 인증(#4. 유저 로그인)
개요
- 로그인 구현
- LoginUser.vue 생성
- 라우팅 추가
- 로그인, 로그아운 UX 추가
- Vuex 적용
Login 페이지 만들기
- Register 페이지에서 로그인 시 필요 없는 name 영역만 삭제하면 된다.
data () {
return {
email: '',
password: ''
}
},
methods: {
login () {
this.$store
.dispatch('login', {
email: this.email,
password: this.password
})
.then(() => { this.$router.push({ name: 'dashboard' }) })
}
}
- login 메소드는 login Vuex Action에 dispatch하고 유져의 email, password를 payload로 보낸다. 정상적으로 처리되면 dashboard route로 리다이렉트된다.(RgisterUser 컴포넌트에서 했던 것들)
- 이제 store.js에 가서 Login Action으로 작성하자.
Vuex: login action 생성
- login Action도 reigster Action이 작동하는 방법과 비슷하다.
- Axios Post 요청이 필요하고 이번엔 서버의 /login endpoint에 요청한다.
- LoginUser 컴포넌트에 payload를 credentials로 보낸다.
login ({ commit }, credentials) {
return axios
.post('//localhost:3000/login', credentials)
.then(({ data }) => {
commit('SET_USER_DATA', data)
})
}
- 서버가 응답하면 data를 받고 SET_USER_DATA에 data를 payload로 넘기고 commit한다.
서버 로그인 로직
- 서버 /login으로 POST하면 db폴더에 있는 user.json 파일을 읽고 서버로 같이 보내진 credentials(email,password)과 비교한다.
- 만약 일치하면 JWT token을 생성하고 생성한 토큰과 응답 데이터(response data)를 반환한다.
- login Action이 SET_USER_DATA mutaion에 커밋하면서 아래와 같이 3단계가 이루어진다.
- VuexState에 userData 저장
- localStorage에 userData 복사본 저장
- Axios Header userData.token 추가
- axios header에 JWT token을 가지고 있으므로 dashboard 경로(route)로 리다이렉트 될때 개인 자료(private event data)에 접근할 수 있어야 한다.
- 이제 LoginUser를 라우트 설정하자
라우터에 LoginUser 추가하기
- router.js에 routes 배열에 추가한다.
/src/router.js
import LoginUser from './views/LoginUser.vue'
...
routes: [
...
{
path: '/login',
name: 'login',
component: LoginUser
}
]
테스트
- localhost:8080:/login에 가서 user.json 저장되어있는 email, password를 입력해라.
- (이 백엔드 서버는 연습용이라 등록수가 1명이다.)
- 로그인 버튼 클릭하고 성공적으로 dashboard로 리다이렉트면 private data가 보여진다.
Home에 라우터 링크 연결
- 현재까지 URL에 /login, /register로 직업 접속했다.
- Home에서 Login, Register 링크를 생성한다.
- 그리고 Login, Register 페이지에서는 각각 Login에서는 Register 링크, Register에서는 Login 링크를 생성한다.(로그인 유무에 따른 처리)
//Home.vue
<div>
To use this app you'll need to
<router-link to="/login">
Login
</router-link>
or
<router-link to="/register">
Register
</router-link>
</div>
// LoginUser.vue
<form>
...
<button type="submit" name="button">
Login
</button>
<router-link to="/register">
Don't have an account? Register.
</router-link>
</form>
// Register.vue
<form>
...
<button type="submit" name="button">
Login
</button>
<router-link to="/login">
Already have an account? Login.
</router-link>
</form>
로그인 버튼 추가
- 상단 GNB 영역에 로그인 버튼 추가하기
/src/components/AppNav.vue
<router-link to="/login" class="button">
Login
</router-link>
- 사용자가 로그인했을때 다시 로그인하거나, 등록하라는 메시지를 보지 말아야 한다.
- 로그인 한 상태인데 login, register 버튼이 보이지 말아야 한다.
- Vuex State를 사용해보자.
로그인 상태일때 Login, Register 보여주지 않기
- 유저가 로그인한 상태이며 로그인하라는 메시지를 보이지 않게 해야 한다. Vuex State를 이용해 Router-links를 숨겨보자.
- this.$store.state.user 표현식을 이용해 템플릿을 수정해보자.
<template>
...
<template v-if="!this.$store.state.user">
<div>
To use this app you'll need to
<router-link to="/login">
Login
</router-link>
or
<router-link to="/register">
Register
</router-link>
</div>
</template>
...
</template>
- 잘 작동하지만 이상적인 방식이 아니다. 템플릿 가독성이 좋길 원한다. Vuex를 잘 모르는 사람(디자이너)가 있을 수 있다.
- 앱이 커질수록 Store를 모듈로 분해하거나 아이템의 이름을 변경하거나 여러가지 이슈들이 있을 수 있다. 이때마다 v-if문을 수정하기는 힘들다.
- 그래서 좋은 방법은 유저가 로그인 했는지 확인하는 getter를 제공하는 것이다. 어떠한 컴포넌트에서 접근 가능한!!
// store.js
...
getters: {
loggedIn (state) {
return !!state.user
}
}
- true이면 로그인 한 상태, false이면 로그아웃상태(null)
- 이제 이 getters를 어떠한 컴포넌트에서든 접근가능하게 만들자.
- src안에 vuex폴더를 만들고 store.js를 여기다 이동시키고, helpers.js를 생성하자.
- helpers.js에 Vuex의 mapGetters를 import 한다.
import { mapGetters } from 'vuex'
export const authComputed = {
...mapGetters(['loggedIn'])
}
- store.js에 있는 getters의 loggedIn 를 mapGetters를 이용해 authComputed로 내보낸다.(export)
- 이제 vuex helper를 import하면 어디서든 사용이 가능하다.
- Home에다 추가해보자.
src/views/Home.vue
<script>
import { authComputed } from '../vuex/helpers.js'
export default {
computed: {
...authComputed
}
}
</script>
- Home 컴포넌트에서 loggedIn getter를 포함한 authComputed를 자유롭게 사용할 수 있다.
<template v-if="!this.$store.state.user">
대신에loggedIn
로 사용할 수 있다.
src/views/Home.vue
<template>
...
<div v-if="!loggedIn">
To use this app you'll need to
<router-link to="/login">
Login
</router-link>
or
<router-link to="/register">
Register
</router-link>
</div>
...
</template>
- AppNav에도 적용 하자.
src/components/AppNav.vue
<template>
<div id="nav">
...
<router-link v-if="!loggedIn" to="/login" class="button">
Login
</router-link>
</div>
</template>
<script>
import { authComputed } from '../vuex/helpers.js'
export default {
computed: {
...authComputed
}
}
</script>
정리
- 로그인 하는 법을 알아봤고, 로그인 유무에 따른 UX를 살펴봤다.(Vuex의 getter를 활용했다.)
- 다음 포스팅은 로그아웃에 대해 알아보겠다. :)
소스코드
728x90
반응형
LIST
'개발일기 > Vue.js' 카테고리의 다른 글
[Vue.js] 토큰 기반 인증 catch 사용 (#6. 에러 처리) (0) | 2020.10.31 |
---|---|
[Vue.js] 토큰 기반 인증(#5. 유저 로그아웃) (0) | 2020.10.30 |
Vue.Js 3 Composition API 살펴보기 - 5(Teleport) (0) | 2020.10.28 |
Vue.Js 3 Composition API에 대해 알아보자 - 4(Sharing State, Suspense) (1) | 2020.10.26 |
Vue.Js 3 Composition API 살펴보기 - 3(Modularzing, LifeCycle Hooks, Watch) (1) | 2020.10.26 |