Node, Vue 일지 #4 (20210907) 회원가입(중복확인), 로그인
4.회원가입(중복확인), 로그인 구현
-회원가입(중복확인)
*기존 회원가입 페이지 이용 (#2 참조)
*중복확인 화면 구현(vue Join.vue)
중복확인 : <div style="display:inline-block" v-text="checkid"></div>
*중복 여부 확인 구현(vue Join.vue)
watch : {
async userid(val) {
const url = "/member/checkid?id=" + val;
const headers = { "Content-Type" : "application/json" };
const response = await axios.get(url, headers);
console.log(response);
if(response.data.ret === 1){ <- 백엔드에서 아이디 조회 후 넘어온 값을 이용해 사용 가능, 불가 출력
if(response.data.data === 1 ){
this.checkid = '사용불가';
}
else{
this.checkid = '사용가능';
}
}
}
},
*node checkid 생성(node member.js)
*아이디 입력 시 monogodb에서 동일한 아이디가 있는지 확인한다.
//중복 확인
router.get('/checkid', async function(req, res, next){
try{
//1. 전달값 받기
//console.log(req.query); <- console.log를 이용해 프론트에서 전달되는 값을 확인한다.
const userid = req.query.id;
//2.db 연결
const dbconn = await mongoclient.connect(mongourl);
const coll = dbconn.db(mongodb).collection(mongocoll);
//3.db에서 조회
const query = { _id : userid };
const result = await coll.countDocuments(query);
//4. 값 전달
res.send({ret:1, data:result});
}
catch(error) {
console.error(error);
res.send({ret:-1, data:error});
}
});
*화면 확인(아이디 중복일 경우)
*아이디 중복일 경우 백엔드에서 data 값을 1을 보내고 프론트엔드에서 '사용불가'를 출력한다.
*화면 확인(아이디 중복이 아닐 경우)
*아이디 중복일 경우 백엔드에서 data 값을 0을 보내고 프론트엔드에서 '사용가능'을 출력한다.
-로그인 구현
*로그인 화면 구성(vue Login.vue)
<div>
<h3>로그인</h3> <hr />
아이디 <input type="text" v-model="userid" /> <br />
비밀번호 <input type="password" v-model="userpw" /> <br />
<input type="submit" @click="handleLogin" value="로그인" />
</div>
*화면 확인
*node login 생성(node member.js)
//127.0.0.1:3000/member/login
router.post('/login', async function(req, res, next){
try{
//전달값 받기
const userid = req.body.userid;
const userpw = req.body.userpw;
//console.log(userid, userpw);
//db연결
const dbconn = await mongoclient.connect(mongourl);
const coll = dbconn.db(mongodb).collection(mongocoll);
//userpw를 hash한 후에 비교 (secret키는 userid(보안키)로 했음) <- 보안키를 어떤 것으로 지정했는지 확인
const hash = crypto.createHmac('sha256', userid).update(userpw).digest('hex');
//db에서 조회
const query = {_id:userid, password:hash};
const result = await coll.findOne(query);
if(result !== null) { <-아이디 비밀번호가 db와 일치하면 토큰을 추가해서 db에 저장
const payload = {idx : result._id } //토큰에 추가할 내용
const token = { //토큰 발행
token : jwt.sign(payload, secretKey, options)
};
//발행된 토큰 db에 추가
const query1 = {_id:userid};
const change1 = { $set : {token : token}};
const result1 = await coll.updateOne(query1, change1);
if(result1.modifiedCount === 1) {
return res.send({ ret:1, jwtToken:token});
}
return res.send({ret:0, data:'로그인 실패'});
}
return res.send({ret:0, data:'로그인 실패'});
}
catch(error){
console.error(error);
return res.send({ret:-1, data:error}); //에러
}
});
*로그인 구현(vue Login.vue)
<script>
import axios from 'axios';
export default {
methods : {
async handleLogin() {
//유효성 검사 <- 로그인 버튼 클릭 시 유효성 검사를 한다.
if(this.userid.length === 0){
return alert('아이디를 입력하세요');
}
if(this.userpw.length === 0){
return alert('비밀번호를 입력하세요');
}
const headers = { "Content-Type" : "application/json" };
const body = {
userid : this.userid,
userpw : this.userpw,
};
const url = "/member/login"
const response = await axios.post(url, body, headers);
console.log(response); //구조 확인 후 아래 진행
if(response.data.ret === 1){
sessionStorage.setItem("MyToken", response.data.jwtToken.token); <- console 창에서 token 경로 확인
//크롬에서 F12 누른후 application에 sessionStorage에 MyToken 저장 확인
alert('로그인 성공');
this.$emit('changeMenu', 0); //홈으로 이동
}
else{
alert(response.data.data);
}
}
},
data() {
return {
userid : '',
userpw : '',
}
}
}
</script>
*로그인 실행(크롬)
*로그인 이후 알림창 확인, 홈 화면으로 이동 확인
-상단 메뉴 설정
*현재 상단 메뉴는 로그인 유무와 상관없이 모든 메뉴가 표시 되고있다.
로그인 성공 시 토큰이 발행되는 것을 이용하여 로그인 유무에 따른 메뉴 표시를 수정한다.
*변수 생성(vue App.vue)
"MyToken" 발행 유무를 확인하여 발행 되었다면 true, 안되었다면 false 설정
created() {
this.changeLogged();
},
methods : {
changeLogged(){
const token = sessionStorage.getItem("MyToken"); //login.vue 참고
if(token !== null) {
this.logged = true;
}
else{
this.logged = false;
}
}
}
*로그인 유무에 따른 메뉴 상태 설정(vue App.vue)
* "!logged" : 로그인 전(token 미발행) / "logged" : 로그인 후(token 발행)
* @changeLogged="changeLogged" 를 삽입해 로그인 이후 메뉴바가 자동으로 수정되도록 설정한다.
<div>
<a href="#" @click="changeMenu(0)">Home</a> |
<a href="#" v-if="!logged" @click="changeMenu(1)">Login</a> |
<a href="#" v-if="!logged" @click="changeMenu(2)">Join</a> |
<a href="#" v-if="logged" @click="changeMenu(3)">Mypage</a> |
<a href="#" v-if="logged" @click="changeMenu(4)">Logout</a>
<hr />
<component @changeMenu="changeMenu" @changeLogged="changeLogged" v-bind:is="currentView"> </component>
</div>
*화면 확인(로그인 전)
*mypage와 logout 은 로그인이 되어야 사용할 수 있는 메뉴이므로 로그인 전에는 표시 하지 않는다.
*화면 확인(로그인 후)
*로그인 이후 자동으로 메뉴바가 변경될 수 있도록 this.$emit('changeLogged'); 를 Login.vue에 홈으로 이동 코드 아래에 삽입시켜준다
alert('로그인 성공');
this.$emit('changeMenu', 0); //홈으로 이동
this.$emit('changeLogged'); //토큰 발행 여부에 따른 메뉴바 자동 표시
*login과 join 은 로그인이 되어야 사용할 수 있는 메뉴이므로 로그인 후에는 표시 하지 않는다.