🤷 기간 : 2021.05.03 ~ 2021.05.03
🤷 자료 : https://www.notion.so/wecode/Django-C-R-U-D-2-98d0ec4c3de844338e769096aee13537
🤷 내용: ORM 과제 리뷰
access token을 클라이언트에게 전송.(JWT)access token을 첨부해서 request를 서버에 전송함으로서 매번 로그인 해도 되지 않도록 한다.단방향 해쉬 함수(one-way hash function)를 쓴다.단방향 해시 함수는 들어온 원본 메세지를 암호화된 메세지(다이제스트(digest))로 변환시킨다"test password"를 hash256이라는 해쉬 함수를 사용용시
->
b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e 값 출력"test password2"를 hash256 해쉬 함수를 사용시'
-> d34b32af5c7bc7f54153e2fdddf251550e7011e846b465e64207e8ccda4c1aeb 값출력 해쉬 함수값은 완전히 다름avalance라고 부른다.In [21]: import hashlib
In [22]: m = hashlib.sha256()
In [23]: m.update(b"test password")
In [24]: m.hexdigest()
Out[24]: '0b47c69b1033498d5f33f5f7d97bb6a3126134751629f4d0185c115db44c094e'In [25]: m = hashlib.sha256()
In [26]: m.update(b"test password2")
In [27]: m.hexdigest()
Out[27]: 'd34b32af5c7bc7f54153e2fdddf251550e7011e846b465e64207e8ccda4c1aeb'Rainbow table attackRainbow table : 미리 해쉬값들을 계산해 놓은 테이블해시 함수는 짧은 시간에 데이터를 검색하기 위해 설계된 것해시 함수는 본래 처리 속도가 최대한 빠르도록 설계 이러한 속성 때문에, 공격자는 매우 빠른 속도로 임의의 문자열의 다이제스트와 해킹할 대상의 다이제스트 비교할 수 있다. 해시값계산단방향 해쉬값을 계산 한 후, 그 해쉬값에 반복하는 해서 해쉬하는 것
In [40]: import bcrypt
In [41]: bcrypt.hashpw(b"secrete password", bcrypt.gensalt())
Out[41]: b'$2b$12$.XIJKgAepSrI5ghrJUaJa.ogLHJHLyY8ikIC.7gDoUMkaMfzNhGo6'
In [42]: bcrypt.hashpw(b"secrete password", bcrypt.gensalt()).hex()
Out[42]: '243262243132242e6b426f39757a69666e344f563852694a43666b5165445469397448446c4d366635613542396847366d5132446d62744b70357353'
유저가 로그인에 성공한 후에는 access token(암호화된 유저 정보)를 첨부해서 request를 보내게 된다.
POST /auth HTTP/1.1
Host: localhost:5000
Content-Type: application/json
{
"username": "joe",
"password": "pass"
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}
그러면 서버에서는 암호화 되어있는 access token을 복호화(<->암호화) 해서 기존 정보를 얻을 수 있다 !
예를들어 access token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E 를 복호화 하면 다음과 같은 정보를 얻는다:
{
user_id = 1
}
위와 같이 복호화해서 얻은 유저 아이디를 통해 해당 유저가 누군지 알 수 있다.
-> 이런 절차의 목적은 해당 유저가 매번 로그인 해도 되지 않도록 하는 것이다.
access token을 생성하는 방법은 여러가지가 있는데, 그 중 가장 널리 사용되는 기술중 하가 바로 JWT(JSON Web Tokens)이다.JWT(JSON Web Tokens) :
해쉬임JWT를 통해서 구현 될 수 있다.access token을 통해 해당 유저 정보를 얻을 수 있음으로 해당 유저가 가지고 있는 권한(permission)도 확인 할 수 있다.access token을 생성한다. access token에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다 (예를 들어 user id).access token을 첨부해서 보낸다.access token을 복호화 한다.bcrypt 설치 및 importpip install bcrypt # 암호화를 위한 "Bcrypt" 라이브러리 설치
import bcrypt # 설치된 "Bcrpyt" import/ python 들어가서 해야해
bcrypt의 암호화 방법!Bytes(이진화) 데이터를 암호화(str 아님)해야함str로 들어온 걸 bytes화를 해야 암호화를 진행 할 수 있다.str -> encode -> bytes 되고, bytes -> decode -> str 화 합니다. encode & decode시 에는 우리가 인식할 수 있는 형태로 변환하기 위해 'UTF-8' 유니코드 문자 규격을 사용해야함bcrypt.hashpw(입력받은 패스워드.encode('utf-8'),bcrypt.gensalt()) 사용password = '1234'
hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) # 암호화 코드 확인해봐
print(hashed_password)
b'$2b$12$YFs9rh.1LgJwZuf9ibyjpuLvBoCaGX0MzedFWF2Jo0zU3lMZurZ4a'
type(hashed_password)
<class 'bytes'> # 바이트 나왔지 ?
- 이렇게 암호화된 방식은 일방향 암호화이며,
- 즉, 복호화 할 수 없도록 암호화하는 방식입니다.
bcrypt.checkpw(입력받은 패스워드.encode(utf-8), 저장된 암호화된 패스워드) 사용입력받은 패스워드.encode(utf-8)와 저장된 암호화된 배스워드는 bytes여야함new_password = '1234'
bcrypt.checkpw(new_password.encode('utf-8'),hashed_password)
TrueJWT(JSON Web Token) 구현pyjwt 설치pip install pyjwt # jwt구현을 위한 pyjwt 설치
access_token) 생성access_token = jwt.encode(헤더값, SECRET, algorithm = 'HS256')을 통한 암호화import jwt # 패키지명은 pyjwt이지만 임포트할때의 이름은 jwt입니다.
SECRET = 'secret' #'랜덤한 조합의 키' 예제이므로 단순하게 'secret'이라고 하겠습니다.
access_token = jwt.encode({'id' : 1}, SECRET, algorithm = 'HS256') # "header값"- {'id' : 1}
print(access_token)
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MX0.-xXA0iKB4mVNvWLYFtt2xNiYkFpObF54J9lj2RwduAI'
이렇게 발급된 토큰은 어떻게 사용할 수 있을까요?
- 바로 프론트에 전달하세요 ! - 어떻게 .. ? ?/
- 로그인이 성공 시, 위 같이 발행한 토큰을 프론트에 전달합시다 !
jwt.decode(access_token, SECRET, algorithm = 'HS256')를 통한 복호화 header = jwt.decode(access_token, SECRET, algorithm = 'HS256')
print(header)
{'id': 1} # 아까 encode한거의 헤더값인 "{'id': 1}"이다 ! !!
이제 ,인증하는 코드는 어디에 구현해야 할까요?
- 바로 엔드포인트에 데코레이터를 구현함돠 !~ !
- 데코레이터 구현은 보통 user app에 utils.py를 만들어서 작성