아하 REST API 서버 개발 (8)
JWT
REST API 에서 사용자를 인증하는 방법은 무수히 많이 존재하지만 대표적으로 OAuth
와 JWT
방식을 가장 많이 사용합니다.
그중 JWT
는 매우 간단한 구조임에도 불구하고 보안성이 상당히 높아서 굉장히 많은 사람들의 사랑을 받고 있죠.
실제로 저희 서비스에서도 JWT
기반으로 사용자를 인증합니다.
JWT
에 대해서 잘 모르시는 분들을 위해 링크를 하나 준비 하였으니 읽어보시고 강좌를 따라와 주시기 바랍니다.
JWT 를 사용하기 위해서는 일단 jsonwebtoken
모듈을 설치하셔야 합니다.
npm install jsonwebtoken
언제나 느끼는 것이지만 npm 은 참 설치하기도 쉽고 사용하기도 쉬운 것 같습니다.
Auth: Login
JWT
를 실질적으로 사용하기에 앞서 email
과 password
로 사용자를 인증하는 로직부터 구현을 해야 합니다.
일단 src/routes/v1/auth.route.js
를 아래와 같이 작성해보도록 합시다.
그리고 src/controllers/v1/auth.controller.js
도 아래와 같이 작성을 해 줍니다.
일단 빈껍데기 상태의 controller 를 만져주기 전에 테스트 코드를 작성해 보도록 합시다.
우리는 POST: /v1/auth/login
라우트로 email
과 password
를 요청하여 응답으로 JWT
를 받아야 하니 해당 로직을 src/tests/integrations/v1/auth.test.js
에 작성하도록 합시다.
자 이제 실제 테스트가 동작하는지 확인해보기 위해 npm test
를 실행시키면
자 이게 바로 TDD
의 묘미 아니겠습니까? 빨간불을 꺼가는 재미.
현재 테스트에서 오류가 생기는 것은 빈껍데기 뿐인 auth.controller.js
때문입니다. 자 그러면 이 로직이 잘 동작할 수 있도록 한줄 한줄 작성해 보도록 하겠습니다.
일단 우리는 요청 body
에 email
과 password
를 전달하였으니 그것부터 받아보도록 합시다.
const email = req.body.emailconst password = req.body.password
email
을 받았으니 그 정보를 가지고 사용자를 찾아야겠죠?
전 강좌에서 User Repository
를 생성한 것을 기억하실 겁니다.
현재 User Repository
에는 email
로 사용자를 조회하는 기능은 없는데요 얼른 후딱 지금 바로 만들어주도록 합시다.
자 이제 email
로 사용자를 조회하는 것은 userRepo.findByEmail(email)
로 호출하면 됩니다만….
한가지가 더 남았죠?
분명 우리는 password
를 평문으로 서버에 제출합니다. 그런데 현재 DB
에는 password
가 이상한 문자열로 암호화가 되어있습니다.
심지어 password
는 해시화 되어 단방향 암호화기 때문에 복호화 할 수 없습니다.
어떻게 해야할까요?
bcrypt
모듈에는 compare
라는 함수가 존재 하는데요 이를 사용하면 평문이 암호화된 해시와 일치 하는지를 검수할 수 있습니다.
src/controllers/v1/auth.controller.js
자 이제 npm test 를 실행해서 우리가 예상하는 로직이 잘 작동하는지 확인해 볼까요?
자 그럼 테스트 케이스를 조금만 더 오밀조밀하게 작성을 해볼까요?
테스트는 정상 동작하니 결과 화면은 패스하도록 하겠습니다.
Response 통일
다음 주제로 넘어가기 전에, 테스트 파일을 자세히 좀 뜯어보도록 하죠.
expect(response.body.data.token).toBeTruthy()expect(response.body.message).toBe('...')
뭔가 이상하지 않습니까? 클라이언트 입장에서는 사실 에러든 성공이든 똑같은 응답일 뿐인데 데이터가 완전히 다른 구조로 전달되고 있습니다.
클라이언트 입장에서 해당 응답이 에러냐 아니냐를 판단하고 서버의 응답 구조까지 신경쓰는것은 확실히 설계가 잘 된 프로그램이라고 생각하지 않습니다.
따라서 서버는 클라이언트에게 항상 한결같은 응답을 주어야 하며, 클라이언트 또한 서버에게 항상 한결같은 요청을 해야 합니다.
그러면 이 작업을 한번 해보도록 하겠습니다.
src/utils/response.js
src/controllers/v1/auth.controller.js
src/app.js
이렇게 수정을 해 주었으니 어디 테스트를 한번 돌려볼까요?
역시 의도된 대로 response.body.message
를 찾을 수 없군요. 그럼 해당 내용을 response.body.data.message
로 변경하여야겠죠?
테스트 파일을 모두 변경 한 후 다시 테스트를 돌리면!
자 그럼 오늘 강좌는 여기까지 하는 것으로 하고 JWT
에 대한 심도있는 강의는 다음 편에 계속하도록 하겠습니다.
말로 하는거면 좀 더 쉬울텐데 글로 소스코드의 변화를 보여주려다 보니 내용도 많이 길어지고 그러는 것 같아 여러분들이 소스코드를 잘 따라오지 못할수도 있겠다 싶었습니다.
그래서 현재 저의 소스를 깃헙에 올려놓고 매 강의마다 태그를 찍어서 공유를 하는것이 좋겠다 싶어서 늦었지만 현재 강의부터 깃헙 소스를 제공하도록 하겠습니다.
소스는 아래 링크에서 clone
부탁드립니다^^