emluy 개발 일기

express.js - passport로 회원가입, 로그인 구현하기 (DB연결 x) 본문

웹 개발/express.js

express.js - passport로 회원가입, 로그인 구현하기 (DB연결 x)

yulme 2020. 8. 20. 15:24
SMALL

*github sourcecode

https://github.com/ImYurim/express-session

 

ImYurim/express-session

Contribute to ImYurim/express-session development by creating an account on GitHub.

github.com

 

 

*현재 이슈

* 갑자기 deserializeUser가 실행 안될 때가 있다. 

-> 해결방안1 : session 의 option 중 secure를 false로 해주면 해결 가능

-> server를 아예 껐다가 다시 키기.

-> 진짜 해결하는 방법은..? 이러는 이유는...???

https://gompro.postype.com/post/1182247

 

Passport.js, 왜 저는 deserialize user 가 실행이 안 되나요?

Passport.js 는 Hello.js 같은 새로운 인증 라이브러리가 등장하는 와중에도 굳건하다.  local strategy 만 해도 npm 다운로드 수 60만에 육박하는 인기를 누리고 있으며, node.js 인증 관련해서 물어보면 Passp

gompro.postype.com

 

 

* 빨리 세션이 저장이 안되거나 로그인 완료 된 후 세션 저장까지 잘 됐는데 메인 홈페이지가 너무 늦게 바뀐다 (로그인하기가 로그아웃하기로 바뀌고 회원가입하기가 없어지고 , 누구님 환영합니다 이것들이 늦게 뜸)

-> 로그인폼에서 제출할때 엔터 누르지 말고 제출을 마우스 클릭으로 로그인 하면 세션 제대로 저장됨 그러나 메인화면이 늦게 바뀜

 

해결 => 로그아웃한 후 빨리 화면이 바뀌게 하기 위해서 req.session.destroy()함수를 써주거나 req.logout() 후 req.session.save()함수를 써주어 빨리 세션이 변경되도록 함

 

 

* 만들 페이지

* 로그인 전

 

* 로그인 후 

 

* 로그인 form

 

* 로그인 실패 시 flash메세지 출력

 

 

 

0. setting

- 작업할 directory 만들기

- 작업할 directory에서 app폴더 만들기( ex) myapp이라는 이름의 app폴더를 만들고 views폴더의 템플릿 파일은 ejs파일로 만들기)

: $express --view=ejs myapp 

 

 

1. main 페이지 템플릿에 로그인, 회원가입 버튼 또는 링크를 만들기

#myapp/views/index.js

 

2. 로그인 페이지, 회원가입 템플릿 페이지 템플릿 만들기

#myapp/views/join/loginform.ejs

#myapp/views/join/joinform.ejs

 

 

3. routes의 index.js에 loginform라우터와 joinform라우터 추가해주기

: loginform 화면이 뜨게 하는 라우터와 joinform이 뜨게 하는 라우터 만들어주기 

#myapp/views/index.js - loginform 띄우는 라우터

 

4. app.js에 passport와 session 모듈 활성화 해주기

4-1. app.js 파일에서 passport, passport-local, express-session, session-file-store, connect-flash 모듈 require해주기

#myapp/app.js

 

4-2. app.js 파일에서 require한 모듈들 활성화 해주기

*순서 매우 중요 : session 모듈 활성화 작성 -> 그 아래에 passport 관련 코드 작성

 

 

*로그인기능

5. loginform에서 login 버튼을 눌렀을 때 작동하는 login 라우터 만들어주기 

5-1. index.js 라우터 파일과 app.js 파일에서 passport, passport-local, express-session, session-file-store 모듈 require해주기

#myapp/routes/index.js

 


5-2. login 라우터가 작동될 때 localstrategy의 local-login 호출하도록 login 라우터 작성해주기 

: loginform에서 로그인 버튼 눌렀을 때 동작하는 router

#myapp/routes/index.js

- 96 : /login 이라는 url이 호출되면

- 97 : passport 의 local-login를 호출하라

- 98 : 성공적으로 login이 되었다면 '/' url을 실행하고 (여기서는 main페이지에 해당됨) 

- 99 : 실패했을 경우 '/loginform' url을 실행시켜라 

 

 

5-3. 아직 DB연결 없이 로그인 되는지 볼 것이기 때문에 임의로 사용자 데이터 객체를 만들어 주고 로그인 해볼 것임

: 임의의 데이터 객체 만들어줌 ( 제일 위쪽 쯤에 만들어주자 )

#myapp/routes/index.js

 

 

 

5-4. passport의 local-login 함수 정의해주기 

:5-2에서 실행되는 local-login 정의

 

#myapp/routes/index.js

- 73 : local-login은 LocalStrategy를 사용한다 ( 다운받아준 passport-local 모듈 )

- 74 : loginform에서 로그인 시 username은 email이다 알려줌 ( loginform에서 입력한 데이터 즉, input 태그의  name 이 email 이었음! 내가 맘대로 지정해주는것 )

- 75 : loginform에서 로그인 시 password는 password이다 라고 알려줌

- 76 : 위에 줄 다 실행 후 callback함수 호출 인자로는 74,75줄의 email 과 password가 넘어옴 (변수이름다르게 해줘도됨)

- 77 : 잘넘어왔나 확인 ( 없어도되는 코드 )

- 78 : 받아온 email이 authData( 5-3 에서 정의한 임의의 사용자 )의 email과 같으면 입력한 아이디로 로그인 할 수 있다는 뜻 -> 원래 db 연결한 상태면 table에서 입력한 email이 있는지 find( ) 해야함

- 79 : 받아온 password도 authData의 password와 맞는지 확인 -> DB연결된 상태면 78번째 줄에서 찾은 row의 password속성 값이 입력한 것과 일치하는지 봐야함

- 80 : 로그인 잘 됐는지 확인용

- 81 : 로그인 성공 후 done에 인자로 err(첫번째 인자)는 null로 보내고 두번째 인자로는 사용자인 것이 식별됐으니까 사용자 정보인 authData를 보내줌

- 82 : 아이디는 맞는데 비밀번호는 틀린 경우

- 83 : 비밀번호 잘못됐다 알려줌

- 84 : err로는 null 을 보내고(이 err는 대게 서버 에러와 관련되어있으므로 null을 보내는 것임, server에 에러가 있는 건 아니고 단지 비밀번호가 아닌것이기 때문에) 두번째 인자로는 정보를 건내주지 않으므로 false를 보내고

- 85 : 세번째 인자로 message를 통해 브라우저에 전달함

- 88 : 아이디 틀린 경우 

- 89 : 아이디 틀렸다 알려줌

- 90 : err도 null 이고 정보도 안건네주고 message에는 아이디 틀렸다고 적어서 브라우저로 보냄

 

 

 

 

5-5. serializeUser와 deserializeUser를 정의해주기

: 5-4. 에서 로그인이 잘 성공해서 81번째 줄에서 done으로 authData를 넘겨준 것이 serializeUser로 온다. 넘어 온 authData중 email만 뽑아서 done을 통해 deserializeUser로 넘겨준다. 넘어 간 email은 사용자가 어떤 페이지를 접속해도 따라다니는 데이터가 된다.

#myapp/routes/index.js

- 60 : 5-4에서 로그인 성공 후 81번째의 done을 통해 넘어온 authData를 serializeUser의 첫번째 인자인 user로 받는다.

- 61 : 잘 왔나 확인 

- 62 : user의 여러 데이터중 (email, password, nickname 중 (5-3 참고) ) email 데이터만 done으로 넘겨준다. 그리고 session store에 정보가 저장됨

- 66 : 62에서 넘겨준 user.email 데이터를 첫번째 인자인 id로 받는다. 

- 67 : 잘 넘어왔는지 확인

- 68 : 잘 넘어온 것을 확인 한 후 그 값을 done을 통해 넘겨줌 -> 이 데이터는 사용자가 어떤 url을 접속하든 계속 따라다니는 data가 될것이다.

 

5-6. 모든것이 잘 성공후 5-2에 의해 main 홈페이지로 넘어간다. 

: 이 때 모든 것이 잘 성공됐는지 확인하기위해 main 홈페이지를 띄우는 router에 deserializeUser가 넘겨준 사용자 정보를 확인해보자

#myapp/routes/index.js

console에 이렇게 뜬다

 

 

5-7. 로그인 됐으니 main page도 변화를 주자 (5-6에서 좀 더 추가)

: 로그인하기 링크는 로그아웃하기 링크로 바꿔주고 회원가입하기는 없애주자

- 어떻게 로그인 됐다고 알 수 있는지? -> req.user가 undefined가 아니면 로그인 성공 후 데이터가 넘어온 것이다!

#myapp/routes/index.js

- 15 : authIsOwner 라는 함수를 만들어 준다. 이 함수는 deserializeUser가 넘겨준 user정보 (email)가 있는지 없는지 확인하는 함수이다.

- 16 : user정보가 있다면 true를 리턴하고

- 18 : user정보가 없다면 false를 리턴한다.

- 24 : main 페이지를 띄우는 라우터

- 25 : user정보가 잘 넘어왔는지 콘솔로 확인 (없어도 됨, authIsOwner가 해줌)

- 29 : authIsOwner를 실행한 결과를 isOwner변수에 저장한다,

- 30 : 넘어온 데이터를 email 변수에 저장한다.

- 31 : 메인페이지에 로그인이 된 상태면 로그아웃하기가 뜨게하고 로그인이 안된 상태면 로그인하기가 뜨게 하기위해 이 문장을 저장하는 변수 userStatus를 만들어준다.

- 32 : isOwner가 있는경우 ( user데이터가 잘 넘어온 경우 즉 로그인이 된경우 ) 

- 33 : userStatus를 로그아웃하기로 바꿔주고 

- 34 : 메인페이지를 띄우고 브라우저로 변수들을 같이 전달한다.

- 35 : 로그인이 안된 경우

- 36 : email에 로그인을 해주세요라는 메세지를 담아 전송해준다.

 

 

 

6. flash 메세지를 브라우저에 띄우기

:5-4에서 정의해 준 함수에서 message 변수가 error 객체에 담겨서 req.flash 안에 저장된다.

* flash

: - 일회성 메세지 -> 페이지 reload하면 없어짐

  - session store에 저장됨 -> 여러이름으로 여러개 저장 가능

 

 

6-1. flash 메세지가 뜨도록 설정해주기 

#myapp/routes/index.js

: 다음과 같이 login을 한 후 실패했을 때 flash 메세지가 뜨도록 118줄을 추가해준다.

 

6-2. loginform 페이지가 뜰 때 5-4로부터 받은 메세지를 같이 출력해주고자 함 

- 50 : deserializeUser가 넘겨준 요청중에 flash 데이터를 flash 변수에 저장함

- 51 : flash에 뭐들어있나 확인용

- 52 : 브라우저에 띄울 내용 담을 변수 선언

- 53 : req.flash에 error 객체가 있다면

- 54 : feedback에 error객체의 첫번째 애를 담아줌 (message를 담은것. 만약 5-4에서 message말고 다른 것도 같이 전송한다면 error객체 안에 여러개가 담겨서 넘어오는 것임 flash.error[1]. flash.error[2] 이런식으로 데이터를 조회할수 있음)

- 57 : 로그인이 안된상태라면 (실패한 경우라면, deserailizeUser가 error를 넘겨줬을 것임)

- 58 : loginform페이지를 다시 띄워주고 feedback 변수도 넘겨준다 브라우저에서 띄울 수 있게

- 59 : 로그인이 된 상태라면 (브라우저에서 로그아웃하기가 띄워져있었을 거고 그걸 지금 누른상태임)

- 60 : 로그아웃해주고 

- 64 : 변경된 세션을 저장해주고 메인페이지를 다시 띄운다 (60번째줄만써도 되긴하지만 브라우저에 반영이 엄청 느리다. 이걸 써주면 빨리 반영되어서 메인페이지가 다시 로그인하기로 바껴있는 모습을 볼 수 있음)

 

6-3. 브라우저에 flash 메세지 띄우기

#myapp/views/join/loginform.ejs

- 9 : feedback이 브라우저에서 띄워지도록 넘어온 경우만

- 10 : 브라우저에서 띄워줌

 

 

 

* 전체 routes/index.js 파일

#myapp/routes/index.js

 

 

* 전체 app.js 파일

#myapp/app.js

반응형
Comments