인증&인가

HYEYOON·2021년 2월 4일
1
post-thumbnail

인증(Authentication) & 인가(Authorization)

인증이란?

-인증은 회원가입과 로그인을 말한다.

1 인증이 왜 필요한가?

-우리 서비스를 누가쓰는지 어떻게 사용하는지? 추적이 가능하도록 하기위해 필요하다.

2 인증에 필요한 것?

-아이디,이메일주소, 비밀번호등
-가장 중요한 것은 비밀번호이다.

3 로그인 절차

1. 유저 아이디와 비번생성
2. 유저 비번 암호화해서 DB저장.
3. 유저 로그인-> 아이디와 비밀번호 입력
4. 유저가 입력한 비밀번호 암호화 한 후 암호화돼서 DB에 저장된 유저 비밀번호와 비교.
5. 일치하면 로그인 성공
6. 로그인 성공하면 access token을 클라이언트에게 전송.
(백엔드 입장에서의 클라이언트는 프론트)
7. 유저는 로그인 성공후 다음부터는 access token을 첨부해서 request를 서버에 전송함으로서 매번 로그인하지 않아도 된다. 

4. 비밀번호 어떻게 관리해야하는가?

  • Database에 저장 시 개인 정보를 해싱하여 복원할 수 없도록 한다.
  • 통신시 개인 정보를 주고받을 때 SSL을 적용하여 암호화(HTTPS)한다.

SSL란?

  • 보안서버, 보안연결
  • 사용자와 웹사이트 간의 통신을 암호화 하여 해커가 중간에 통신 데이터를 가로채더라도 어떤 내용인지 알 수 없게 하는 통신 방법이다.

5. 암호화는 어떻게 할까?

5.1 단방향 해쉬란?

-원본 메세지를 변환하여 암호화된 메세지인 다이제스트(digest)를 생성한다. 원본 메세지를 알면 암호화된 메세지를 구하기는 쉽지만, 암호화된 메세지로는 원본 메세지를 구할 수 없어서 단방향(one-way)라고 한다.
-본래 해쉬(hash)함수는 자료구조에서 빠른 자료의 검색, 데이터의 위변조 체크를 위해서 쓰이지만, 복원이 불가능한 단방향 해쉬함수는 암호학적 용도로 사용한다.
해쉬는 자료구조의 일종
-(MD5, SHA-1)(둘은 보안취약),SHA-256등이 있다.
-'1234'를 SHA-256 해싱하면 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4와 같다.
-결과만 봐서는 당장 식별이 불가능하므로 완벽해보인다.
-하지만 같은 알고리즘으로 '1234'를 다시 해싱하면 항상 같은 결과가 도출된다.

* SALTING & KeyStretching

말그대로 소금치고 늘린다?

-단순해쉬값이 해킹에 쉽게 노출되기 때문에 솔팅이라는 아이디어가 생겼다.
-입력한 비밀번호와 임의로 생성한 문자열(salt)을 합쳐서 해싱해서 이 해시값을 저장하는 방법이다.
이때 비교를 위해 해시값과 소금값을 같이 저장한다.
-여기에 해커가 패스워드 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해 salting및 해싱을 여러번 반복해서 원본 값을 유추하기 어렵게 만드는 것이 키 스트래칭이다.

5.2 bcrypt

-salting& key stretching을 구현한 해쉬 함수중 가장 널리 사용되는 것
-단방향 해쉬 함수의 취약점
-Rainbow table attack - 미리 해쉬값들을 계산해 놓은 테이블을 rainbow table이라고 한다.
-bcrypt는 앞서 말한 개념들을 실제로 적용하기 편하게 해주는 대표적인 라이브러리이다.
-다양한 언어를 지원하고 있으며, 사용이 간편하여 쉽게 적용이 가능하다.
-bcrypt는 hash결과값에 소금값과 해시값 및 반복횟수를 같이 보관하기 떄문에 비밀번호 해싱을 적용하는데 있어 DB설계를 복잡하게 할 필요가 없다.

In [40]: import bcrypt

In [41]: bcrypt.hashpw(b"secret password", bcrypt.gensalt())
Out[41]: b'$2b$12$.XIJKgAepSrI5ghrJUaJa.ogLHJHLyY8ikIC.7gDoUMkaMfzNhGo6'

In [42]: bcrypt.hashpw(b"secret password", bcrypt.gensalt()).hex()
Out[42]: '243262243132242e6b426f39757a69666e344f563852694a43666b5165445469397448446c4d366635613542396847366d5132446d62744b70357353'

-bcrypt를 통해 해싱된 결과값의 구조는 아래와 같다.

JWT(JSON Web Tokens)

-앞에서 언급했듯이 유저가 로그인에 성공한 후에는 access token이라고 하는 암호화된 유저 정보를 첨부해서 request를 보내게 된다.
-유저정보를 담은 JSON데이터를 암호화해서 클라이언트와 서버간에 주고 받는 것.
예_

  • 유저 로그인:
POST /auth HTTP/1.1
Host: localhost:5000
Content-Type: application/json

{
    "username": "joe",
    "password": "pass"
}
  • access token:
HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}

이렇게 되면 서버에서는 access token을 복호화해서 해당 유저 정보를 얻게된다.
user_id = 1 이렇게...복호화해서 유저아이디를 통해 유저를 알 수 있게된다.


인가란 ?

-권한이 있는 유저인가 확인하는 절차=사용자가 서버에 로그인하면 해당 사용자가 맞는지 확인하는 과정
-해당 유저는 고객 정보를 볼 수는 있지만 수정할 수 없다는 것?
@바로 Request/ Response 요청과 응답.
@
stateless한 성질(저장하지 않는 성질).

  • 서버는 사용자가 로그인 했을 경우, 로그인했다는것을 어떻게 알수 있을까?
    바로 headers에 메타데이터를 보내서 확인한다.
    이 메타정보를 바로 JSON Web Token 이라고 한다.
  • 인가 절차
    1. Authentication 절차를 통해 access token을 생성한다. access token에는 유저 정보를 확인할 수 있는 정보가 들어가야한다. (ex: user_id)
    2. 유저가 request를 보낼때 access token을 첨부해서 보낸다.
    3. 서버에서는 유저가 보낸 access token을 복호화 한다.
    4. 복호화된 데이터를 통해 user id를 얻는다.
    5. user id를 사용해서 database에서 해당 유저의 권한을 확인한다.
    6. 유저가 충분한 권한을 가지고 있으면 해당 요청을 처리한다.
    7. 유저가 권한을 가지고 있지 않으면 Unauthorized Response(401)혹은 다른 에러 코드를 보낸다.
profile
Back-End Developer🌱

2개의 댓글

comment-user-thumbnail
2021년 2월 5일

썸네일 출처가 어딘가욤 냥이가 너무 귀엽네요,,

1개의 답글