인증(Authentication)과 인가(Authorization)

Daye Kang·2019년 12월 22일
20
post-custom-banner

인증과 인가

  1. 인증이란?
    유저가 누구인지 확인하는 절차, 회원가입하고 로그인 하는 것.

  2. 인가란?
    유저에 대한 권한을 허락하는 것.

  • 누가, 언제, 어떻게 쓰고 있는가를 파악하기 위해 어떤 사이트에서든 인증, 인가가 있음.
  • 인증과 인가는 API에서 가장 자주 구현되는 기능중 하나.
  • Private한 API는 물론이고 Public한 API도 기본적인 인증과 인가를 요구.

인증

Q. 어떻게 하면 정보를 첨부해 통신을 보낼 수 있을까? 민감한 정보는 아니면서 일정시간 동안 유효하게, 그리고 도용되지 않게.

opt1. 아이디와 비밀번호를 같이 보낸다. => 매번 서버에서 확인을 해야 함, 정보의 민감성
opt2. 시간제한이 있는 임시 아이디를 보낸다 => 어떤 유저인지 파악하기 힘듦, 그 유저의 정보를 또 따로 저장을 해야 함.(실제 유저 정보와 맵핑을 따로 해야 함)
opt3. 일정 시간 동안 인가에 유효한 정보로 대체한다. ==> JWT(JSON Web Tokens) 이용

======= JWT ========

  • table ID를 준다.
  • 그 정보를 JSON 형태로 전달(객체)
  • 유효기간도 전달
  • { "id": 1,
    "exp": 2019_12_19
    }
  • http headers(주요한 내용을 넣는)에서 이용할 수 있도록 JSON 을 'token'화 함.
  • '.'을 기준으로 3부분으로 나뉘어짐.
  • 첫번째, 두번째는 코드화(encoding), 누구든 decode 할 수 있음
  • 마지막은 암호화(복호화를 아무나 하지 못함, 웹코드를 서버한 페이지는 할 수 있음), 도용의 문제를 막기 위해
  • 다른 서버는 복호화를 할 수 없음. => 인가가 안 됨
  • 서버가 직접 발행한 웹토큰만 복호화할 수 있음
  • Authorization header 부분에 같이 첨부해서 보냄. 프론트에서 리퀘스트가 있으면 저장하고 있던 토큰을 백에 첨부해서 같이 보냄.

Q. 유저의 비밀번호 암호화는 어떻게 해야 할까?

  • 유저의 비밀번호는 절대 비밀번호 그대로 DB에 저장 하지 않음.
    DB가 해킹을 당하면 유저의 비밀번호도 그대로 노출될 뿐더러 내부 개발자나 인력이 그 정보를 볼 수 있음. ==> 유저의 비밀번호는 꼭 암호화 해서 저장!!

  • 비밀번호 암호에는 단방향 해쉬 함수(one-way hash function)가 일반적으로 쓰임.
    단방향 암호화. (복호화가 안 되는 암호, 원본의 문자를 알아낼 수가 없음), 외부에서 정보가 해킹당했을때, 내부에서 정보가 유출될 때를 모두 대비해 단방향 암호화로 만듦.

Q. 암호화된 문자의 원본을 어떻게 알 수 있을까?

  • 동일한 알고리즘을 이용하면 동일한 값이 나옴.
  • 복호화해서 확인할 수 없기 때문에 똑같은 알고리즘을 이용해 동일한 결과값이 나오면 같은 값인 것을 알 수 있음. ==> 암호화값이 다르면 원본값이 다른 것. 유저의 비밀번호 원본 문자는 서버에서 알 수가 없음.
  • 클라이언트가 암호화하는 것이 아니라 서버쪽에서 암호화 하는 것. 백에서 암호화를 맞춰봄.

단방향 암호화를 decoding 하는 방법

*Bruceforce Attack: 무식하게 같은 값이 나올 때까지 모든 암호값을 다 때려 맞춰보는 것. 조합 가능한 숫자와 문자, 특수기호 등을 다 조합해 봐야 하므로 시간이 너무 많이 걸림.

*Rainbow Atack: 미리 계산된 테이블을 갖고 조합해보는 것. 서칭을 해봄으로써 원본값을 찾을 수 있음.

  • 'rainbow attack'이 가능한 이유: 해쉬 암호화는 연산화되는 시간이 짧음. 비밀번호를 암호화하기 위해 만든 알고리즘이 아니기 때문에 누구라도 쉽게 값을 찾아낼 수 있음.

기존의 단방향 해쉬에서 진화한 암호 알고리즘 ===>>>
'Bcrypt': 1) Salting : 원본값에 '소금을 뿌리듯이' random값을 추가 하는 것.
2) Key Chaining : 연산을 느리기 위해 해쉬 값이 구해지면 그 해쉬 값을 기반으로 또 해쉬를 하고 해쉬를 하고 n번 하는 것. 최종값을 저장. => rainbow attack이 어려워짐.

==> 단방향 해쉬 함수의 단점을 보완

인가

:유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차.

  • 'JWT'를 쓰면 인가가 수월함. 서버가 유저 정보를 갖고 있으므로 데이터에서 유저의 권한 정보도 읽어들이면 됨.
  • 'access token'을 통해 해당 유저 정보를 얻을 수 있음으로 해당 유저가 가지고 있는 권한(permission)도 확인 가능.

Authorization 절차

  1. Authentication 절차를 통해 access token을 생성한다. access token에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다 (예를 들어 user id).
  2. 유저가 request를 보낼때 access token을 첨부해서 보낸다.
  3. 서버에서는 유저가 보낸 access token을 복호화 한다.
  4. 복호화된 데이터를 통해 user id를 얻는다.
  5. user id를 사용해서 database에서 해당 유저의 권한(permission)을 확인하다.
  6. 유저가 충분한 권한을 가지고 있으면 해당 요청을 처리한다.
  7. 유저가 권한을 가지고 있지 않으면 Unauthorized Response(401) 혹은 다른 에러 코드를 보낸다.

// reference: https://stackoverflow.com/c/wecode/questions/125

profile
뭐든 하자
post-custom-banner

0개의 댓글