TIL #69 : [Web] 인증, 인가

셀레스틴 허·2021년 2월 11일
0
post-thumbnail

🔑 인증


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

인증을 통해 우리는 사용자가 서비스를 누가 어떻게 사용하는지(데이터)를 본다.

인증을 위해 필요한 요소는 대표적으로 아이디, 비밀번호, 이메일이 있다. 사용자 정보가 무방비하게 보관되면 해킹 당할 수 있기 때문에 비밀번호 같은 경우는 암호화를 통해 (데이터베이스에 저장될 때 해시화 시켜) 해커의 공격 또는 다른 사람들에 의해 유출, 노출되지 않게 한다.

크롬 같은 경우는 :
https -> 으로 시작하는 사이트는 안전한 사이트,
http -> 으로 시작하는 사이트는 안전하지 않은 사이트라고 뜬다.

암호화

해시함수는 자료구조에서 빠른 자료의 검색, 데이터의 위변조 체크를 위해서 쓰인다. 암호화할 때는 복원이 불가능한 단방향 해시 함수를 써 암호학적 용도로 사용한다.그러나 해시 함수만으로는 보안에 취약하기 때문에 salting, key-stretching을 이용한다. 데이터에 의미없는 문자열을 추가(salting) 및 길이를 늘린다(key-stretching).

암호 생성 : 비밀번호 + 솔트값 = 해시 + 추가적인솔트값
암호 verification : 비밀번호 + 저장된솔트값 vs 해시 + 추가적인솔트값

암호화 오픈소스 라이브러리

bcrypt : 솔팅, 키 스트레칭 라이브러리

bcrypt는 해시 결과값에 소금값과 해시값, 및 반복횟수를 같이 보관하기 때문에 비밀번호 해싱을 적용하는데 있어 DB를 복잡하고 설계할 필요가 없다.

bcrypt 설치하기

$ pip install bcrypt

🔑 인가


인가 : 사용자가 서버에 로그인 하면 해당 사용자가 맞는지 확인하는 과정이다.
HTTP의 stateless, request, response를 이용해서 JSON web Token 즉 JWT를 사용한다.

HTTP 통신 때 우리는 body에 데이터를 담아서 보낸다. 보통 데이터는 body에 담지만 토큰 같은 경우는 headers에 포함해서 보낸다! 이 토큰 즉, JWT가 사용자가 맞는지 보장해주는 것이다.

JWT는 header(헤더), payload(내용), signature(서명)이 포함된다.

  1. 헤더에는 토큰의 타입과 해시 알고리즘 정보가 들어간다. 그리고 헤더의 내용은 BASE64 방식으로 인코딩해서 JWT의 가장 첫부분에 기록된다.

  2. payload는 내가 실제로 넘기고 싶은 사용자의 내용, 정보다. 여기에 담긴 내용은 사용자의 PK 즉 id값이다. 사용자의 id값과 exp같은 만료시간을 BASE64 인코딩을 통해 두번째 요소로 배치한다.

  3. 서명은 '확인'할 때 사용되는 부분이다. 서명은 BASE64URL 인코드된 header와 payload, 그리고 JWT secret을 헤더에 지정된 암호 알고리즘으로 암호화해 전송한다. (복호화 가능함) 프론트엔드가 JWT를 백엔드 api 서버로 전송하면 서버에서는 전송 받은 JWT의 서명 부분을 복호화하여 서버에서 생성한 JWT가 맞는지 확인한다.(만약 다르면 다른 사용자를 의미한다.) 여기서 주의해야 할 점은 header, payload는 BASE64 인코딩한 것이므로 누구나 원본을 볼 수 있으니 개인정보를 담아서는 안된다!

프론트엔드가 계속 JWT를 헤더에 담아서 요청을 전송하면 백엔드는 JWT값 안에 있는 PK값을 확인하고 데이터베이스 안에 있는 '우리' 사용자가 맞으면 요청을 실행한다.

PyJWT 설치하기

$ pip install PyJWT

🔑 실습


장고쉘로 사용자를 하나 만든다.

>>> User.objects.create(name="Minji Huh", email="minji@huh.com", password="7894@pppp", username="Febeleven")
<User: User object (31)>
mysql> select * from users;
+----+-------------+----------------------+--------------------------------------------------------------+--------------+----------------------------+----------------------------+---------------+
| id | name        | email                | password                                                     | username     | created_at                 | modified_at                | phone         |
+----+-------------+----------------------+--------------------------------------------------------------+--------------+----------------------------+----------------------------+---------------+
|  1 | chaehyunnim | cnim@naver.com       | $2b$12$QFc94pzweFzKrUPCepBHb.Z1tCEodzl7CrJGQJssQoKImWyWNjiXS | goyangee1004 | 2021-02-04 14:43:40.536359 | 2021-02-04 14:43:40.536387 | 010-1234-5678 |
|  2 | macbook     | jagoshipda@naver.com | $2b$12$B5762VpB93jmX.kAA.lzp.S9xW0GQybpPGZeVvku.evpfTwcCDBqO | highlighter  | 2021-02-04 17:39:34.352507 | 2021-02-04 17:39:34.352536 | 010-1234-9876 |
|  3 | phillips001 | phillips@gmail.com   | $2b$12$5gI/8.WD6X9sgHqRBPuYx.mRd5KSXJfHQuNq6wzL/9YUV.4pG6fJi | mousecat     | 2021-02-09 11:14:11.271520 | 2021-02-09 11:14:11.271547 | 010-1234-6666 |
| 27 |             | js@js.com            | $2b$12$KIIm6RoLqJIXXpGJ.Dlwuew3xj2CHHdrfRX7PsE/Ir..0.VibYecO |              | 2021-02-10 07:34:33.391419 | 2021-02-10 07:34:33.391450 | NULL          |
| 31 | Minji Huh   | minji@huh.com        | 7894@pppp                                                    | Febeleven    | 2021-02-11 12:08:52.800036 | 2021-02-11 12:08:52.800073 | NULL          |
+----+-------------+----------------------+--------------------------------------------------------------+--------------+----------------------------+----------------------------+---------------+
5 rows in set (0.00 sec)

mysql을 확인하면 비밀번호가 그대로 암호화가 되어있지 않은 상태로 DB에 들어간 것을 확인할 수 있다. 그럼 이제 HTTP 통신을 통해서 새로운 사용자를 만들어 보겠다.

HTTP REQUEST로 사용자 만들기 (with 암호화 코드)

SUCCESS HTTP REQUEST

http -v POST 127.0.0.1:8000/user/signup name="Minhee Kim" email="minheek@gmail.com" password="7894@pppp" username="thisisminhee" phone="010-0000-1111"

SUCCESS HTTP RESULT

{
    "email": "minheek@gmail.com",
    "name": "Minhee Kim",
    "password": "7894@pppp",
    "phone": "010-0000-1111",
    "username": "thisisminhee"
}


HTTP/1.1 200 OK
Content-Length: 22
Content-Type: application/json
Date: Thu, 11 Feb 2021 12:13:40 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.9.1
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "message": "SUCCESS"
}

자 이제 mysql을 확인해 보면...

mysql> mysql> select * from users;
+----+-------------+----------------------+--------------------------------------------------------------+--------------+----------------------------+----------------------------+---------------+
| id | name        | email                | password                                                     | username     | created_at                 | modified_at                | phone         |
+----+-------------+----------------------+--------------------------------------------------------------+--------------+----------------------------+----------------------------+---------------+
|  1 | chaehyunnim | cnim@naver.com       | $2b$12$QFc94pzweFzKrUPCepBHb.Z1tCEodzl7CrJGQJssQoKImWyWNjiXS | goyangee1004 | 2021-02-04 14:43:40.536359 | 2021-02-04 14:43:40.536387 | 010-1234-5678 |
|  2 | macbook     | jagoshipda@naver.com | $2b$12$B5762VpB93jmX.kAA.lzp.S9xW0GQybpPGZeVvku.evpfTwcCDBqO | highlighter  | 2021-02-04 17:39:34.352507 | 2021-02-04 17:39:34.352536 | 010-1234-9876 |
|  3 | phillips001 | phillips@gmail.com   | $2b$12$5gI/8.WD6X9sgHqRBPuYx.mRd5KSXJfHQuNq6wzL/9YUV.4pG6fJi | mousecat     | 2021-02-09 11:14:11.271520 | 2021-02-09 11:14:11.271547 | 010-1234-6666 |
| 27 |             | js@js.com            | $2b$12$KIIm6RoLqJIXXpGJ.Dlwuew3xj2CHHdrfRX7PsE/Ir..0.VibYecO |              | 2021-02-10 07:34:33.391419 | 2021-02-10 07:34:33.391450 | NULL          |
| 31 | Minji Huh   | minji@huh.com        | 7894@pppp                                                    | Febeleven    | 2021-02-11 12:08:52.800036 | 2021-02-11 12:08:52.800073 | NULL          |
| 32 | Minhee Kim  | minheek@gmail.com    | $2b$12$ITTiukEroZPS/o3JxdtPgeS/dYxcw72G6KpdBX8w51oCu7y4/.sdu | thisisminhee | 2021-02-11 12:13:40.399742 | 2021-02-11 12:13:40.399770 | 010-0000-1111 |
+----+-------------+----------------------+--------------------------------------------------------------+--------------+----------------------------+----------------------------+---------------+
6 rows in set (0.00 sec)

id #6번 보면 해시화된 암호가 들어간 것을 확인할 수 있다!

암호화 비밀번호 구현 코드(/signup)

암호화 비밀번호 check 코드(/signin)

profile
Software Developer / 고통은 필연, 괴로움은 선택

0개의 댓글