인증과 인가는 API에서 가장 자주 구현되는 기능중 하나이다.
1. 인증이란?
- 유저의 아이디와 비번을 확인하는 절차
- 인증을 하기 위해서 먼저 유저의 아이디와 비밀번호를 생성할 수 있는 기능이 필요하다.
로그인 절차
- 유저 아이디&비밀번호 생성
- 유저 비밀번호를 암호화 하여 DB에 저장
- 유저 로그인 -> 아이디와 비밀번호 입력
- 유저가 입력한 비밀번호를 암호화 한 후, 암호화되어 DB에 저장된 유저 비밀번호와 비교
- 일치하면 로그인 성공
- 로그인 성공하면 access token을 클라이언트에게 전송
- 유저가 로그인 성공 후 그 다음부터는
access token
을 첨부해서 request를 서버에 전송함으로써 매번 로그인 해도 되지 않도록 한다.
2. 비밀번호 암호화는 어떻게 이루어지는가?
- 유저의 비밀번호는 절대 비밀번호 그대로 DB에 저장하지 않는다. DB가 해킹 당하면 유저의 비밀번호가 그대로 노출 되기 때문이다. 따라서 유저의 비밀번호는 꼭 암호화 해서 저장해야 한다. 이렇게 하면 해킹을 당해도 비밀번호가 노출되지 않는다.
- 비밀번호 암호에는 일반적으로 단방향 해쉬 함수(one-way hash function)가 쓰인다.
3. 단방향 해쉬 함수 그리고 레인보우 테이블 어택
단방향 해쉬 함수
- 단방향 해쉬 함수는 원본 메시지를 변환하여 암호화된 메시지인
다이제스트(digest)
를 생성한다. 원본 메시지를 알면 암호화된 메시지를 구하기는 쉽지만 암호화된 메시지로는 원본 메시지를 구할 수 없어서 단방향성
이라고 한다.
- 예를 들어, "test password"를 hash256이라는 해쉬 함수를 사용하면
0b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e
라는 값이 나온다.
레인보우 테이블 어택
- 미리 해쉬값들을 계산해 놓은 테이블을 Rainbow table이라고 한다.
4. 설팅과 키스트레칭 그리고 bcrypt
Salting
- 실제 비밀번호 이외에 추가적으로 랜덤 데이터를 더해서 해쉬 값을 계산하는 방법
Key Stretching
- 단방향 해쉬값을 계산 한 후 그 해쉬 값을 또 해쉬 하고, 또 이를 반복하는 것을 말한다.
- 최근에는 일반적인 장비로 1초에 50억 개 이상의 다이제스트를 비교할 수 있지만, 키 스트레칭을 적용하여 동일한 장비에서 1초에 5번 정도만 비교할 수 있게 한다.
bycrypt
- Salting과 Key Stretching을 구현한 해쉬 함수 중 가장 널리 사용되는 것이 bcrypt이다.
- bcrypt는 처음부터 비밀번호를 단방향 암호화 하기 위해 만들이전 해쉬 함수이다.
5. 인가란?
- 인가(Authorization)는 유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인지 확인하는 절차이다
- 인가도 JWT를 통해서 구현 될 수 있다.
- access token을 통해 해당 유저 정보를 얻을 수 있음으로, 해당 유저가 가지고 있는 권한도 확인 할 수 있다.
6. JWT에 대해
(JSON Web Tokens)
- 유저가 로그인에 성공한 후에는 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.
- 그러면 서버에서는 access token을 복호화 해서 해당 유저 정보를 얻게 된다.
- 복호화해서 얻은 유저 아이디를 통해 해당 유저가 누군지 알 수 있다.
- access token을 생성하는 방법은 여러가지가 있는데, 그 중 가장 널리 사용되는 기술 중 하가 바로 JWT(JSON Web Tokens)이다.
- JWT는 말 그대로 유저 정보를 담음 JSON 데이터를 암호화 해서 클라이언트와 서버간에 주고 받는 것이다.