API 개발을 하다보니 기존에 만들었던 API 목록에서 잘못된 부분들이 보였다. 일부 사항들은 수정을 했고, Provider/Service나 DAO 부분도 서버에서 불필요하게 처리하는 부분들을 리팩토링 했다. 그리고 이번에는 JWT를 이용해서 회원가입과 로그인을 구현해볼 것이다.
📖 강의 주제
- Cookie, Session & JWT
로그인 방식의 이해와 Validation을 고려한 개발 방법
📝 목표
- 트랜잭션
- JWT
- OAuth
▶️ 개발 일지
1. 강의 내용 정리
1) HTTP 특징
- Stateless : 현재 상태나 데이터를 저장하지 않는다.
- 로그인을 하거나 사용자 인증을 했을 때 그 상태를 저장하지 않고 매번 인증해야 한다.
2) 세션과 쿠키
- 세션은 서버쪽의 임시 저장소로 클라이언트의 정보를 저장한다.
- 쿠키는 클라이언트에서 서버의 정보를 저장한다.
- 웹 캐시는 응답시간을 최소화 하기 위해 방문 사이트의 정보를 가지고 있는 것이다.
3) JWT
- 세션과 쿠키의 장점을 더해서 인증을 매번 하되 직접적으로 인증 정보를 보내거나 받지 않는다.
- 클라이언트가 서버에 인증 요청을 하면, 서버는 JWT를 발급 받아서 클라이언트에 전달한다.
클라이언트는 자신의 저장소에 토큰을 저장한다.
다음 요청이 필요할 때 클라이언트는 저장된 토큰을 사용하여 별도의 추가 인증없이 서버로부터 응답을 받을 수 있다.
- 구성은 Header, Payload, Signature로 돼있다.
- Header : 인코딩 방식
- Payload : 사용자를 구분할 수 있고 탈취되도 문제가 되지 않는 정보 저장
- Signature : Header와 Payload의 인코딩 값. Secret Key 값을 저장
4) 트랜잭션
- Commit : 쿼리를 작성하고 DB에 수정사항을 반영할 때 사용
- Rollback : DB 수정사항을 취소할 때 사용
- DB의 작업을 하나로 묶어주는 용도다.
- 주로 POST나 PATCH와 같이 클라이언트와 서버 모두 반영 되거나 모두 반영되지 말아야 할 때 쓰인다.
2. 트랜잭션
1) 개념 및 특징
- 트랜잭션의 핵심은 데이터베이스에 특정 명령이 데이터베이스에 모두 반영되거나 모두 반영되지 않는 것이다.
이를 조금 쉽게 표현하자면 아래 그림과 같이 회전문으로 나타낼 수 있다.
- 각 회전문 칸을 트랜잭션으로 보면, 명령들이 몇 개가 있든 하나의 트랜잭션은 모두 적용되어 오른쪽으로 나가든지 아니면 모두 적용되지 않고 다시 왼쪽으로 빠져 나온다.
- 또 회전문이 칸으로 나뉘어져 있듯이 트랜잭션은 서로 간섭하지 않고, 격리된 채로 실행된다.
- 데이터베이스에 변화가 생기는 명령인 Insert, Update, Delete 위주로 트랜잭션을 적용한다.
Select는 조회하다가 실패하더라도 데이터베이스에 변화가 생기지 않기 때문에 적용하지 않는다.
2) 적용
- Node.js의 mysql 모듈에서는 쉽게 트랜잭션을 적용하도록 메소드를 제공한다.
- 자바스크립트의 async/await 문법과 병행하여 트랜잭션을 적용하면 아래와 같이 사용할 수 있다.
async transactionFuction(parameter1, parameter2, parameter3) {
const connection = await pool.getConnection(async (conn) => conn);
try {
await connection.beginTransaction();
await insertSomething(parameter1);
await updateSomething(parameter2);
await deleteSomething(parameter3);
await connection.commit();
return 'success!'
} catch (error) {
await connection.rollback();
return error;
} finally {
connection.release();
}
}
- beginTransaction 메소드으로 트랜잭션을 시작한다.
commit 메소드는 명령이 모두 실행된 뒤 커밋을 시작한다.
rollback 메소드는 에러 발생시 롤백을 시작한다.
3. JWT
1) 인증 프로세스
- JSON Web Token의 약자로 전자 서명된 JSON이다.
- 서버와 클라이언트간 정보를 주고받을 때 HTTP Request Header에 JSON 토큰을 넣은 뒤, 별도의 인증과정 없이 서버는 JWT의 정보를 사용해 인증한다.
- 토큰 안에는 사용자를 식별할 수 있는 정보만 넣고, 절대!! 비밀번호는 토큰 안에 넣으면 안된다. JWT는 탈취당하면 쉽게 내용을 볼 수 있기 때문이다.
- JWT의 인증 프로세스를 도식화하면 아래와 같다. (내용 출처[2])
2) JWT 발급
- Node.js의 모듈 중 jsonwebtoken을 사용해서 JWT를 발급했다. 발급은 클라이언트에서 로그인 요청을 보낼 때 이루어진다.
const jwt = require('jsonwebtoken');
const token = asycn function(userIdRows) {
return await jwt.sign(
{
userId: userIdRows[0]
},
'secret_key_blahblah!!',
{
expiresIn: '365d',
subject: 'userInfo'
}
);
}
3) JWT 확인
- 클라이언트에 발급한 JWT를 통해 서버에 접근 제어를 하려면 다시 JWT를 확인해서 사용자가 맞는지 확인해야 한다.
- Express 프레임워크의 주요 기능인 미들웨어를 통해 JWT 확인을 구현 한 뒤 요청을 처리하는 것이 좋다. 미들웨어 코드를 직접 올리기는 힘들어서 확인 과정 중 일부만 첨부했다.
const jwt = require('jsonwebtoken');
const token = req.headers['jwtValue'];
const checkJWT = async function() {
await jwt.verify(jwtValue, 'secret_key_blahblah!!', (err, chekcedToken) => {
if (err) throw err;
return checkedToken;
});
}
4. OAuth
- OAuth는 서버에서 직접 사용자의 정보를 관리하는 것이 아닌 제 3자의 서버를 통해 사용자를 직간접적으로 관리하는 방법이다.
OAuth부터는 아직 서버에 적용을 해보지 못했다😟 아직 Express와 OAuth에 대한 내용 이해가 부족한 것 같아서 좀 더 지식을 쌓은 뒤에 다시 도전해볼 예정이다!
& 링크모음
[1] : 라이징캠프
[2] : JWT란?
둘리님을 응원합니다.