Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

자스알못의 JS 이야기

(Node.js) JWT authentication 구현 본문

Node.js

(Node.js) JWT authentication 구현

문과공도리 2016. 12. 6. 09:42


저번에 react에서 개인 프로젝트 소개하면서, 간단하게 로그인 기능 구현하는 거를 소개했었는데요.

http://js-almot-story.tistory.com/5


이번에는 연결된 차원에서 node.js 를 통해서 어떻게 authentication 을 구현했는지를 간단하게(?) 소개를 해보려고 합니다!


1. 필요한 모듈

1) Node.js && NPM
2) passport, passport-local
3) jsonwebtoken
4) bcrypt


*) 옵션으로 유저 정보를 저장할 mysql와 seqelize도 있으면 좋겠죠


2. 구성 원리
바로 코드로 들어가서..!
유저가 로그인을 하면, 아래있는 라우트로 요청을 합니다. ( /auth/login )


< controller / user.authentication.controller.js >


코드에서 보이는 것처럼, 순서대로 보자면


1) req.checkBody( ~~ ).notEmpty
먼저 req.body에 id, 와 password 가 notEmpty 인지 체크를 하고

2) passport.authenticate('local' , (err, user, info) => { ~~  }
둘다 들어왔다면 passport 쪽으로 authenticate 메서드를 실행하는데, 우리는 OAuth 같은 것을 쓰지 않았기 때문에 local strategy를 사용합니다.
( passport 는 strategy 라는 개념으로 인증 방식을 구분하는 것 같습니다. )

3) Callback !!
인증에 성공해서 user 를 인자로 받으면, 뒤의 로직이 진행이 되고, 아니면 next() 로 errorhandling을 해줍니다.

그러면 이제, passport 쪽에서 설정을 해줘야 하는데요.
밑에서 설명하겠지만 jwt를 써서 session이 따로 필요가 없으므로, serialize 같은 메서드를 안쓰고, 바로 strategy 단위로  require를 해서 쓰도록 하겠습니다.


< config / passport.local.js >


일반적으로 id 와 password를 체크해서 인증을 하는 local strategy 인데, 변수 설명을 조금만 하면
User 는 sequelize 객체로, 현재는 DB의 User 테이블을 의미한다고 보시면 됩니다. 거기서 email이 userEmail인 user 하나를 찾아라 라는 것이죠

그 다음에 user가 없다면 아이디가 없는 것이고, 있다면 password 체크를 해야 되는데 여기서 나오는 부분이 user의 authenticate 가 나옵니다. 제가 User 테이블을 정의해놓을 때 만들었던 DB의 메서드 인데, 소스로 간략하게 확인하겠습니다.


< models / User.js >


부분에 instanceMethods 를 보면, authenticate와 hashPassword가 있는데, 이름처럼 인증과 비밀번호 암호화입니다.

비밀번호를 평문으로 보관하면 안되기 때문에 10자리의 salt를 넣어서 hash를 만들어 저장하고, 비밀번호를 확인할 때도 bcrypt 를 이용해 일치 여부를 확인합니다.

이렇게 인증이 끝났으면 다시 위로 올라가서 나머지 로직을 봅시다.


< controller / user.authentication.controller.js >


보실때 주의하실 점은, jwt 가 jsonwebtoken 모듈이 아니라, 따로 설정해둔 jwt config파일을 참조하는 것이며, generateToken 메서드도 따로 거기서 만들어놓은 메서드입니다. 원래는 jsonwebtoken 모듈 설명  보시면 아시겠지만, jwt.sign 으로 토큰을 생성합니다.

jwt 는 json web token의 약자로, 말그대로 json 형태의 인증 토큰입니다.
자세한 내용은 https://jwt.io 를 확인하시고...
여기서 구조는 아래와 같습니다.



전체적으로 보면, 로그인을 할 때 Refresh Token, Access Token 을 넘겨줍니다. 두개를 넘겨주는 이유는 용도가 다른데, 


Refresh Token 은 Auth Server로의 인증을 위한 토큰으로, 만료 기간이 길고, 사용 횟수가 적으며, 보관이 중요합니다.


Access Token 은 일반 Resource를 가져올 때 인증을 위한 것으로, 보통 사용자가 하는 대부분의 요청의 header 에 붙여서 날리게 됩니다. 상대적으로 refresh token보다 만료기간이 짧고, 계속 붙여 보내는 만큼 사용 횟수가 많고, 물론 이것도 보관이 중요하지만 만료기간이 짧기 때문에 리스크가 적습니다.

기존의 session 서버를 따로 두어서, 요청마다 거기를 거치는 것보다 간단하고, signature 복호화 키만 알고 있으면 어디서든지 복호화를 할 수 있기 때문에 서버의 로드 밸런싱을 할 때도 어렵지 않게 인증을 처리할 수 있습니다.

이제 거의 끝 마무리 입니다..!!
로그인 시에 Refresh Token, Json Web Token 을 넘겨주었으니

1) 프론트 단에서 요청마다 미들웨어로 athorization header 달아주기
2) express middleware 로 header 체크 해서 로그인 여부 구분하는 로직 달기

를 해주면 되는데, 1번은 제가 리액트를 접한지 얼마 되지 않은 관계로, 저도 시도해보고 있고
2번은 바로 아래에! 있습니다.


< config / express.js >


앞 부분은 그냥 header authorization 이 있는지 확인하는 과정이고, authenticate 를 한 후, req.user 에 user 를 달아주면 추후 처리하는 과정에서 req 의 user 를 바로 사용할 수 있습니다.

이렇게 첫 node 게시글을 써봤는데, 제가 이거 처음에 할 때 삽질을 을마나 했던지... 사실 아직도 세션과 쿠키는 안써봐서 정확히 모르는데, 일단 잘 작동하고 있다는 것에 안도감을 느낍니다..ㅎㅎ
그런데 저번에 썼던 글처럼 jwt 와 refresh token을 어디에 저장해야 하는지에 대해서 의문이 남아있어서 아시는 분은 댓글 부탁드립니다 :)




Comments