기존에 구현에 실패해왔던 기능이다.
우리 페이지에서는 로그인을 해야만 들어갈 수 있는 사진탭, 공지사항, 승부차기 탭이 있다.
그런데 메뉴를 누르고 탭을 접근해도 로그인을 하면 다시 홈화면으로 가져서 번거로운 단점이 있었고,
공지사항 링크를 한 번에 운영진들이 공지할 때에도 로그인페이지로 이동된다음 다시 홈화면으로 이동되어서
다시 유저가 직접 공지사항을 찾아가야하는 번거로움이 있었다.
이를 해결하기위해서 구현해야하는 기능이었다.
기존에 알아본 방법으로는 우선, session 을 이용해야했는데
다시 천천히 접근을 해보기로 했다.
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
next();
} else {
req.session.returnTo = req.originalUrl;
var send_url = req.session.returnTo
res.render('login', { Needlogin_Message: '로그인이 필요합니다.'});
}
};
내 로그인 미들포인트다.
위에서는 send_url 를 console 로 찍어보면 원래 접근하려 했던 url 이 나왔다.
app.get('/login', exports.isNotLoggedIn, async (req, res, next) => {
res.render('login.ejs');
});
app.post('/login', async (req, res, next) => {
passport.authenticate('local', (error, user, info) => {
if (error) return res.status(500).json({ success: false, message: '서버 에러' });
if (!user) return res.status(401).json({ success: false, message: info.message });
req.logIn(user, (err) => {
if (err) return next(err);
delete req.session.returnTo;
return res.json({ success: true });
});
})(req, res, next);
});
기존에는 위의 저 send_url 값을 어떻게든 login 탭으로 가져오려고 했는데 실패했었다.
이번에는 생각을 좀 더 간단하게 해서 그냥 저 미들포인트에서 직접 NeedLogin_Message 변수를 전달하듯이 send_url 을 전달해보기로 했다.
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
next();
} else {
req.session.returnTo = req.originalUrl;
var send_url = req.session.returnTo
res.render('login', { Needlogin_Message: '로그인이 필요합니다.', send_url });
}
};
그리고 가져온 값을 로그인 버튼을 눌렀을 때 작동하는
function handleLoginFormSubmit() {
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: document.getElementById('id-input').value,
password: document.getElementById('password-input').value,
}),
})
.then(response => response.json())
.then(data => {
if (data.success) {
var send_url2 = '<%=send_url%>'
window.location.href = send_url2;
} else {
alert('아이디 또는 비밀번호를 확인해주세요.');
}
})
.catch(error => {
console.error('에러:', error);
});
return false;
}
handleLoginFormSubmit() 함수에 data 가 받아졌을 시에 변수선언을 해버린다.
이렇게 하니까 접근을 하고자 했던 주소로 이어서 접속이 가능했다 !!
그러고 좋아하던 차에
생각해보니 그냥 로그인버튼을 홈화면에서 눌러서 접근하는 경우는 send_url 이 아무런 데이터를 가져오지 않은
상태이기 때문에 에러가 났다.
근데 기존에 사용했던 방법인
<% if (typeof Needlogin_Message !=='undefined' ) { %>
<script>
alert('<%= Needlogin_Message %>');
</script>
<% } %>
이런 형식으로 똑같이 했는데
if (typeof '<%=send_url%>' !=='undefined' ) {
var send_url2 = '<%=send_url%>'
} else {
var send_url2 = '/'
}
이 코드에서는 send_url is not defined 에러가 떴다.
내 추측으로는 위에Needlogin_Message 같은 경우는 변수가 선언은 되어있는 상태였고 안에 undefined 로 되어있기
때문에 위 코드가 유효했지만
기존 접근하려한 주소가 아예 없다보니 서버측에서
req.session.returnTo = req.originalUrl;
코드가 아예 무의미했고 send_url 변수 자체가 선언이 안되어있는 상태인가? 싶었다.
변수가 선언은 되어있는 상태에서 안에 아무런 데이터가 없으면 undefined 로 뜨기 때문이다.
그럼 서버측에서 손을 써야한다고 판단이 들었다.
exports.isLoggedIn = (req, res, next) => {
if (req.isAuthenticated()) {
next();
} else {
req.session.returnTo = req.originalUrl;
var send_url = req.session.returnTo
res.render('login', { Needlogin_Message: '로그인이 필요합니다.', send_url });
}
};
이 코드를 다시 천천히 정리해봐야겠다.
잠깐 머리 식히면서 생각을 해봤는데.
그냥 홈 화면에서 로그인 버튼을 눌러서 들어가는 로그인 페이지에는 위의 미들웨어가 작동하지 않지 않나!?
그래서
app.get('/login', exports.isNotLoggedIn, async (req, res, next) => {
var send_url = '/'
res.render('login', {send_url});
});
이처럼 login 엔드포인트로 접근하는 경우에는 send_url 을 그냥 홈 화면으로 이동할 수 있게끔 / 값을 넣어줬다.
function handleLoginFormSubmit() {
var send_url2 = '<%=send_url%>';
fetch('/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: document.getElementById('id-input').value,
password: document.getElementById('password-input').value,
}),
})
.then(response => response.json())
.then(data => {
if (data.success) {
window.location.href = send_url2;
} else {
alert('아이디 또는 비밀번호를 확인해주세요.');
}
})
.catch(error => {
console.error('에러:', error);
});
return false;
}
그러고 함수 코드를 위처럼 다시 정리해주었다.
정상작동했다!!
굿!!! 너무 오래걸렸다 이 기능 구현하는데에. 뿌듯하다.