인증과 인가는 API에서 가장 자주 구현되는 기능중 하나이다. 프라이빗한 API는 물론이고 퍼블릭한 API도 기본적인 인증과 인가를 요구한다.
인증이란?
- Authentication은 유저의 identification을 확인하는 절차이다. 쉽게 말해 유저의 아이디와 비밀번호를 확인하는 절차.
- 인증을 하기 위해서는 먼저 유저의 아이디와 비밀번호를 생성할 수 있는 기능이 필요하다.
인증이 필요한 이유는?
- 우리 서비스를 누가 쓰는지? 어떻게 사용하는지? 추적이 가능하도록 하기위해 필요하다.
로그인 절차
- 유저 아이디와 비밀번호 생성
- 유저 비밀번호 암호화해서 DB에 저장
- 유저 로그인 -> 아이디와 비밀번호 입력
- 유저가 입력한 비밀번호 암호화 한 후 암호화되서 DB에 지정된 유저 비밀번호와 비교
- 일치 -> 성공
- 로그인 성공하면
access token
을 클라이언트에게 전송
- 유저는 로그인 성공 후 다음부터
access token
을 첨부해서 request를 서버에 전송함으로서 매번 로그인하지 않아도 된다.
유저 비밀번호 암호화
-
유저의 비밀번호는 절대 비밀번호 그대로 DB에 저장하지 않는다.
:DB가 해킹당하면 비밀번호 그대로 노출될 위험과 외부 해킹이 아니더라도 내부 개발자나 인력이 유저의 비밀번호를 볼 수 있기 때문
-
유저의 비밀번호는 반드시 암호화해서 저장해야 한다.
:DB가 해킹을 당해도 비밀전호가 그대로 노출되지 않으며, 내부인력도 비밀번호를 알 수 없기 때문
-
비밀번호 암호에는 단방향 해쉬함수 (one-way hash function)가 일반적으로 쓰인다. (실제로 비슷한 비밀번호라도 해쉬값은 완전히 다르게 부여됨)
단방향 해쉬함수 그리고 레인보우 테이블 어택
단방향 해쉬 함수에도 몇가지 취약점이 있다.
Salting과 KeyStretching 그리고 bcrypt
Salting
- 말그대로 소금치고 늘린다!?
- 실제 비밀번호 이외에 추가적으로 랜덤 데이터를 더해서 해시값을 계산하는 방법
- 이 때 비교를 위해 해시값과 소금(Salt)값을 같이 저장해야 한다.
- 해커가 패스워드 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 늘리기 위해 원본값을 유추하기 어렵게 만드는 것이 키 스트레칭.
Key Stretching
- 단방향 해시값을 계산 한 후 그 해시값을 또 해쉬하고 또 해쉬하고.. 또 반복하는 것
bcrypt
- Salting 과 Key Stretching의 대표적 라이브러리
- Salting 과 Key Stretching을 구현한 해쉬 함수 중 가장 널리 사용되는 것이 bcrypt.
양뱡향도 있다. 예를들어 병원에서는 개인정보를 암호화 해야 하지만 또 이를 다시 복호화 시켜서 사용할 수도 있어야 하기 때문에.
인가란?
- 사용자가 서버에 로그인하면 해당 사용ㅈ가 맞는지를 확인하는 것이 인가이다.
- 인가를 하는 이유는 HTTP특징 때문. request/response 요청과 응답 , stateless(요청 하나하나가 독립적인) 특징
- 위의 특징 때문에 서버는 사용자가 로그인 했을 때 로그인 했다는 것을 어떻게 알 수 있을까?
:바로 headers에 메타데이터를 보내서 확인.
JWT
- 이 메타 정보를 바로 JSON Web Token 일명 JWT라고 한다.
- 헤더 : JWT를 어떻게 검증하느냐에 관한 내용을 담고있다. 암호화 하지않고 인코딩만 한다.
- 내용 : 암호화 하지 않고 인코딩만 한다. 바로 식별할 수 없게만 해줌
- 서명 : JWT가 원본 그대로라는 것을 확인할 때 사용. 각 웹서비스에 고유한 키를 암호화함.