지난번 회원가입 기능 구현에 이어 로그인 기능까지 구현했다 !
추가로 로그인 이후 jwt 토큰을 발행하여 로그인 이후 계속 인증이 유효하도록 하였다.
관련 내용을 진행하면서 특이사항을 정리해보고자 한다.
# 구현하고자 하는 것
- 회원가입된 정보를 바탕으로 로그인 기능 구현하기 !
- 로그인 시 jwt토큰 발행하여 인증 유효하게 하기 !
** 로그인 시 요구사항
1) 이메일 또는 비밀번호가 일치하지 않을 경우 에러메시지
(비밀번호는 해시된 상태이기에 맞춰서 비교해야함 !)
2) jwt 토큰 안에는 유저ID를 담아야하고 유효기간은 12시간으로 설정
3) jwt 토큰 인증에 실패할 경우 알맞은 에러코드와 메시지 반환
# 로그인 기능
로그인이 진행되는 단계 !
1. 유저가 body에서 이메일, 비밀번호를 입력한다.
2. 입력된 이메일과 비밀번호를 DB와 일치 여부 확인
3. 불일치 시 에러 메시지
4. 일치 시 인증 토큰 발행
1. 유저가 입력된 데이터 가져오기
router.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
const user = await Users.findOne({ where: { email } });
로그인 요청 경로를 localhost:3000/api/login 으로 설정했다.
요청된 바디에서 email과 password를 가져오고, Users모델 안에서 email이 동일한 데이터를 user 변수에 할당했다.
2. 로그인 시 유효성 검사
// email이 없을 경우 (기존 회원이 아닌 경우) or 비밀번호를 잘못 입력하였을 경우
// 비밀번호 비교 시 bcrypt.compare 메서드를 통해 해싱 진행
if (!user || !(await bcrypt.compare(password, user.password))) { // 모델에 집어넣어보기?
res.status(401).json({ errorMessage: "이메일 또는 비밀번호를 확인해주세요." });
return;
};
할당된 데이터가 없을 경우(이메일이 일치하지 않거나 기존 회원이 아닐 경우)와 비밀번호가 일치하지 않을 때 에러가 발생한 경우
401 응답코드와 에러메시지를 반환한다.
HTTP 응답코드에 대해서 많이 헷갈리고 있는데 아래 MDN 문서를 보면서 참고하고 있다.
https://developer.mozilla.org/ko/docs/Web/HTTP/Status
HTTP 상태 코드 - HTTP | MDN
HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려줍니다. 응답은 5개의 그룹으로 나누어집니다: 정보를 제공하는 응답, 성공적인 응답, 리다이렉트, 클라이언트 에러, 그리고
developer.mozilla.org
추가로 보안을 위해 에러 메시지를 구체적으로 반환하는게 좋지 않다고 하는데
(예를 들어 이메일이 잘못되었을 경우와 비밀번호가 일치하지 않는 경우를 각각 나눠서 응답을 보내는 경우)
관련 내용은 아래 사이트를 참고하였다.
Authentication - OWASP Cheat Sheet Series
Authentication Cheat Sheet Introduction Authentication is the process of verifying that an individual, entity or website is whom it claims to be. Authentication in the context of web applications is commonly performed by submitting a username or ID and one
cheatsheetseries.owasp.org
추가로 위에서도 언급하였지만 회원가입 시 비밀번호를 DB에 저장할 때 암호화하여 저장하였기에
입력된 비밀번호와 비교할 때에도 HASH 하는 작업이 필요하다 !
이때에는 bcrypt.compare() 메서드를 활용할 수 있다.
bcrypt.compare(비밀번호, 해시하여 저장된 비밀번호)
if (!user || !(await bcrypt.compare(password, user.password))) {
res.status(401).json({ errorMessage: "이메일 또는 비밀번호를 확인해주세요." });
해당 메서드는 불리언 값을 반환하기 때문에 조건문의 조건으로 사용할 수 있다.
흠.. 코드 리뷰를 하다가 bcrypt.comapre() 메서드를 모델에 넣어서 사용해보라는 조언을 받았는데 관련해서는
프로젝트를 1차로 완성 후 리펙토링할 때 시도해보고자 한다.
3. 로그인 성공 시 jwt 토큰 발행 !
jwt토큰에 대해서는 별도로 포스팅을 하는게 좋을 것 같지만 우선은 인증을 위한 도구 정도로 이해하면 좋을 듯 하다.
로그인 후에는 인증된 사용자이기 때문에 다른 서비스도 이용 할 수 있게한다.
// 로그인 시 jwt 토큰 생성 생성
const token = jwt.sign({ userId: user.id }, process.env.SECRET_KEY, { expiresIn: "12h" });
res.cookie("authorization", `Bearer ${token}`);
jwt 토큰을 이용하기 위해서는 jsonwebtoken 이라고 하는 라이브러리를 설치해야하는데,
설치 후에는 위와 같이 sign 메서드를 활용해서 토큰을 만들어주었다.
요 토큰을 활용하여 사용자 인증을 하기 위해서는 미들웨어를 추가해야하는데 !
미들웨어에서는 다음 포스팅에서 진행하는게 좋을듯 하다 !
'프로젝트 진행기' 카테고리의 다른 글
| 끝판왕의 프로젝트_Node.js 뉴스피드 만들기_팀프로젝트 (1) | 2023.11.21 |
|---|---|
| 끝판왕의 프로젝트_Node.js CRUD 실습(4)_미들웨어 구축 (0) | 2023.11.17 |
| 끝판왕의 프로젝트_Node.js CRUD 실습(2)_회원가입 (1) | 2023.11.15 |
| 끝판왕의 프로젝트_Node.js CRUD 실습 (0) | 2023.11.06 |
| 끝판왕의 프로젝트_영화 검색 사이트 만들기(심화) (0) | 2023.10.27 |