8. Vue.js+Node.js 웹페이지 만들기
[Node.js] Passport 로그인 구현 (express & vue)
Login 구현
MySQL + Vue + express + passport를 이용하여 구현해본다.
vuex 에러
vuex code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree
- 위의 예제에 따라 로그인을 구현하던 중 vuex가 설치되지 않는 문제가 발생하였다.
npm i vuex --save --legacy-peer-deps
- 이런 식으로 설치를 진행하면 정상적으로 설치가 된다.
Backend
백엔드에 사용할 코드는 vue 웹페이지 만들기 1~4까지 만드는데 사용했던 백엔드를 그대로 활용할 예정이다.
npm 설치
express-session passport passport-local dotenv
대부분의 백엔드 세팅 과정은 위의 블로그를 참고하면 문제 없이 동작한다.
주의할 점
app.use(passport.initialize());
app.use(passport.session());
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api/login', loginRouter);
- 백엔드 app.js를 작성하고 난 뒤 로그인 기능을 실행하려 할 때 isAuthenticated에서 에러가 발생하는 경우가 있다. 이는 위와같이 passport.initialize와 session이 먼저 실행되지 않고 라우터 설정 보다 늦게 나올 경우 에러가 발생한다. 따로 언급되어있지 않기 때문에 주의하자.
Frontend
참고 블로그는 Vue 2.0으로 작성된 듯 하다. 현재 내가 사용하고 있는 vue 3.0과 모듈 사용 방법에 있어 약간의 차이가 존재한다.
frontend npm 설치
npm i vuex
- store에서 vue의 actions, mutations, state를 관리하기 용이하도록 만들어준다.
store/index.js
import { createStore } from "vuex";
export default createStore({
state: {
user:null
},
getters: {
user: (state) => { return state.user;}
},
mutations: {
setUser(state, user) { state.user = user;}
}
});
- vue 3.0 vuex 사용법 참고
main.js
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import './assets/tailwind.css'
import axios from 'axios'
import VueAxios from 'vue-axios'
import VCalendar from 'v-calendar';
import router from './router'
import PerfectScrollbar from 'vue3-perfect-scrollbar'
import 'vue3-perfect-scrollbar/dist/vue3-perfect-scrollbar.css'
import store from './store';
// createApp(App).mount('#app')
const app = createApp(App).use(router)
app.use(store)
app.use(VueAxios, axios)
app.use(PerfectScrollbar)
app.use(ElementPlus)
app.use(VCalendar, {})
app.mount('#app')
- store와 VueAxios를 추가하였다.
- vuex는 store에서 사용되는중
IndexPage.vue
<template>
<div class="py-10">
<div v-if="user">
<h1 class="text-yellow-500 text-6xl py-2">User Information</h1>
<p class="text-white text-4xl py-2">ID : </p>
<p class="text-white text-4xl py-2">Name : </p>
</div>
</div>
</template>
<script>
export default {
created() {
this.$http
.get("/api/login")
.then((res) => {
const user = res.data.user;
if (user) {
this.$store.commit("setUser", user);
} else {
this.$router.push({ name: "Login" });
}
})
.catch((err) => {
console.error(err);
});
},
computed: {
user() {
return this.$store.getters.user;
},
},
};
</script>
- 만약 user가 존재하지 않는다면 Login 페이지로 넘어간다.
- user가 존재할 경우 ID와 Name을 보여준다
Login.vue
<template>
<div>
<div class="my-10 mx-10 pt-10">
<form @submit.prevent="onSubmit">
<p class="text-white ">아이디</p>
<input type="text" name="id" v-model="id" />
<p class="text-white">비밀번호</p>
<input type="password" name="password" v-model="password" />
<p></p>
<button type="submit" class="text-white hover:text-yellow-500">
로그인
</button>
</form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
id: "",
password: "",
};
},
methods: {
onSubmit() {
console.log("submit");
const id = this.id;
const password = this.password;
console.log(id, password);
this.$http
.post(
"api/login",
{ id, password },
{ "Content-Type": "application-json" }
)
.then((res) => {
if (res.data.user) {
this.$store.commit("setUser", res.data.user);
this.$router.push({
name: "IndexPage",
});
} else if (res.data.message) {
alert(res.data.message);
}
})
.catch((err) => {
console.error(err);
});
},
},
};
</script>
- backend로 ID와 password를 보내 결과를 확인한다.
추가해야 할 것
- 로그아웃 기능
- 회원가입 기능
- json 파일에서 mysql로 데이터 이동
- 로그인 UI 변경