너무나 재미지다.
세션123 수업을 듣고나니
회원가입 파트는 intro 만들어도 저절로 코드가 짜지게 된다...
짜면서도 스스로 감탄한다. 어떻게 이렇게 재밌을 수 있는것인가.
2번쨰 3번째 동영상을 듣기 전 내가 짠 코드와 비교해보니
정확하게 일치했다.
너무나 기쁘고 즐겁다.
코딩은 너무나 재미난 놀이이다.
빨리 저 휘발성 강한 file 말고 sql 로도 db 관리를 해보고싶다
존경하는 이고잉님을 위해 제 코드를 공개합니다.
php로 작성한 코드입니다. 로직은 어디에서나 동일하니 이런 기능이 필요한 분들은 각종 언어로 재작성하시면 되겠네요.
이 강의분에서만 이고잉님이 악전고투하시는 것 같아서요.
for문 로직 이상 --> 개선 필요.
아래 코드에서는
아이디 존재 유무와 패스워드 비교 수행 후 로그인 성공시 세션정보 생성 및 리다이렉션까지를 담았습니다.
---------------------------------------------------------------------------------------------------------------------
/* 사용자 아이디 존재유무 확인
등록된 사용자라면 필요한 데이터를 가져와 아래에서 패스워드 비교에 사용
에러메시지는 모두 세션정보로 처리, 리다이렉션 받은 페이지에서 alert로 보여주거나 화면 디스플레이함 */
$sql = "SELECT userID, userPassword, userName FROM users WHERE userID ="."'".$_POST['userID']."'";
$result = mysqli_query($conn, $sql);
if($result->num_rows == 0) {
// 존재하지 않는 아이디
$serverMsg = "등록되지 않은 아이디입니다.";
$_SESSION['serverMsg'] = $serverMsg;
session_write_close();
header("Location: http://".$_SERVER['HTTP_HOST']."/login.php");
die();
exit;
} else {
$row = mysqli_fetch_assoc($result);
}
/* 로그인 성공시, 세션정보 생성, 특정 페이지로 리다이렉션
로그인 실패시, 에러메시지와 함께 로그인 페이지로 돌려보냄 */
if($row['userPassword'] == $_POST['userPassword']){
$_SESSION['userID'] = $row['userID'];
$_SESSION['userName'] = $row['userName'];
$_SESSION['isLogined'] = true;
session_write_close();
header("Location: http://".$_SERVER['HTTP_HOST']."/index.php");
die();
exit;
}
} else {
$serverMsg = "패스워드를 잘못 입력하셨습니다.";
$_SESSION['serverMsg'] = $serverMsg;
session_write_close();
header("Location: http://".$_SERVER['HTTP_HOST']."/login.php");
die();
exit;
}
// 사용자 인증 처리 끝
토픽 프로그램과 다중 사용자 시스템을 하나로 합쳤습니다.
그러다 보니 로그인한 상태와 사용자 이름 표시를 모든 템플릿에서 접근하기 위해 다음과 같이 코드를 추가했습니다.
// 세션에서 로그인한 사용자의 이름을 res.locals 에 저장하는 미들웨어
app.use(function(req, res, next){
if(req.session.displayName) // 세션에 사용자 이름이 있을 때
res.locals.whoami = req.session.displayName;
next();
});
// res.locals 로 변수를 저장하면 템플릿 렌더링할 때 변수를 넘겨 주지 않아도 사용이 가능하다.
// jade 문서의 상단 메뉴에 로그인, 회원 가입 버튼 처리
if whoami
a(href="/auth/profile")
span.glyphicon.glyphicon-user
| #{whoami} 님
li
a(href="/auth/logout")
span.glyphicon.glyphicon-log-out
| 로그아웃
else
li
a(href="/auth/login")
span.glyphicon.glyphicon-log-in
| 로그인
li
a(href="/auth/register")
span.glyphicon.glyphicon-check
| 회원가입
login에서는 다중사용자이기 때문에 users배열의 모든 사용자정보를 비교해야했습니다.
그러기 위해서 for문을 사용했죠. for문은 반복문이기 때문에 해당 유저를 찾았으면 더 이상 반복하지 않고
끝내야 합니다. 그래서 return을 사용한거죠. 그렇치 않으면 for문이 종료되고 나서 who are you 코드가 실행될겁니다.
register에서 그리고 이전 세션 강좌에서 return이 없는 이유는 굳이 그 부분에서 함수를 종료시켜 빠져나올 필요가 없었기 때문입니다. return으로 빠져 나와도, 빠져나오지 않아도 그 아래에서 실행되어지는 코드가 없는거죠.
post('/auth/login')에서 는 return 을 하고 세션 저장을 하셨는데
post('/auth/register')에서는 return을 안하셨습니다. 그런데도 잘 등록이 되고 웰컴페이지로
잘 리다이렉트 됩니다. register에서 리턴을 안하신 이유가 있는지요..?
덧붙이자면, 이전 세션 강좌에서는 post login에서도 return이 없었는데 이유가 궁금합니다:)
전역 배열 변수에 데이터는 브라우져를 새로 고치거나 다른 페이지로 가면 다시 초기화 되요. 유저 로긴여부는 Session Data 로 로긴 상태를 정하는거구요. 원래 전역 배열변수로 유저 가입을 저장하는게 아니에요. 하지만 이수업에 본래 목적은 egoing 님이 말한것처럼 복잡성을 우선 제외하고 로긴부분인 수업을 집중한거에요.
egoing님 잼있는 강의 늘 감사합니다.
강의 내용을 보면서 따라하다가 이러면 어떨까라는 생각이 드는 부분이 있어서 코멘트를 남기며 질문도 있습니다.
강의 내용 중 아래의 코드 부분에 displayName를 삭제하고 save를 하는 식으로 logout을 진행하셨는데요.
app.get('/auth/logout', function(req,res){
delete req.session.displayName;
req.session.save(function(){
res.redirect('/welcome');
});
로그아웃시에는 session의 정보를 삭제하는 것이 옳지 않나 라는 들어서 찾아본 결과
save 말고 delete라던가 regenerate등의 정보가 있더라구요.
아래의 코드를 수행시키면 기존의 session 값은 사라지고 새로운 sesison 파일이 생성되며 displayname값도 사라지게 됩니다.
req.session.regenerate(function(err){
res.redirect('/welcome');
});
개인적인 생각으로는
DB에서 변경(Update) 속도가 빠르다면 전체 값을 초기화 해주는 방법을 찾는게 좋을 것 같으나,
삭제 생성의 속도도 문제가 되지 않는다면 session에 들어간 모든 값을 초기화 해주는 방법은 아무래도 재생성이 맞는 것 같기도 합니다.
질문사항
실제 상용 서버에서는 보통 해당 상황에서는 어떻게 진행하는지요?
로그인에 관련된 특수한 정보만 지우고 나머지 세션값은 가지고 있는지요?
단순히 naver를 확인해보니 로그인을 할 경우 cookie에 my.naver.com이라는 값이 새로 생기고 로그아웃의 경우 사라지고 있네요. 허허허 역시 상용서버는 많이 복잡복잡하네요.
찾는 부분은 콜백과 상관 없으므로
불리언 변수 혹은 i 값 체크해서 처리하면 될 것 같습니다.
var f = false; // 찾는 루틴 전에 선언.
for (var i = 0; i < user.lenght; i++) {
if (아이디, 패스워드가 일치하면) {
f = true;
~~~
}
}
// 밖에서
if (!f) {
res.send('who are you?~~~;
}
혹은 불리언 변수 선언 없이
if (i == user.lengh) {
res.send('who are you?~~~;
}
로 해도 되는 듯, 못찾으면 i값이 최종적으로 저 값이 되니까요.
(이 경우 아이디,패스 찾는 for문의 경우 찾았으면 루프 탈출하는 break문을 추가해야 될것 같아요.)