특정 상태를 유지하기 위해서 쓰인다. http의 통신의 특징에서 각 통신은 독립성을 지니기 때문에 이전의 통신을 기억하지 못한다.
ex .로그인을 하고나서 장바구니로 들어갔을 때 이전의 로그인한 통신을 장바구니로 들어갔는 통신이 기억을 못하기 때문에 다시 로그인을 해야한다. 만약 로그인을 하고 서버에서 토큰을 받아 장바구니로 들어가는 request에 token을 첨부해서 보내면 이 유저는 로그인 되었다는 것이 기억이 되는 효과를 가진다.
특정 서비스를 이용하는 권한을 부여할 때 쓰인다.
ex. 로그인을 해서 내가 로그인상태가 유지되는 토큰을 발행 받았어도 유료서비스를 이용하기 위해서는 결제를 해야한다. 이 때, 결제를하고나서 받은 토큰을 권한이 걸린페이지에 들어가는 reqeust를 보낼 때 첨부해서 보낸다.
django를 통해서 로그인에 성공한 유저에게 토큰을 발행해보자.
우선 전체적인 로그인 + 토큰발행 코드는 다음과 같다.
lass LoginView(View):
def post(self, request):
data = json.loads(request.body)
try:
if Account.objects.filter(name=data['name']).exists():
user = Account.objects.get(name=data['name'])
user_password = user.password
if bcrypt.checkpw(data['password'].encode('utf-8'), user_password.encode('utf-8')):
token = jwt.encode({'name' : data['name']}, 'wecode', algorithm = 'HS256')
return JsonResponse({'token':token.decode('utf-8')}, status = 200)
유저가 보낸 POST request의 name과 password가 데이터베이스에 존재하면
token = jwt.encode({'name' : data['name']}, 'wecode', algorithm = 'HS256')
return JsonResponse({'token':token.decode('utf-8')}, status = 200)
토큰을 발행해주고 발행된 토큰과 200 ok를 json으로 return한다.
jwt.encode({'name' : data['name']}, 'wecode', algorithm = 'HS256')
jwt(Json Web Token)는 (유저정보, secret key, 암호화방식에 해당하는 알고리즘종류)를 혼합하여 encode해서 token을 만들어준다. 예시의 경우 유저에게 받은이름을 유저정보로, wecode를 secret key로 알고리즘의 종류는 HS256으로 해서 token을 조합한다. 추후에 이 토큰정보를 담은 request를 다시 유저데이터로 복호화하기 위해서 secret key를 사용한다.
POST /accounts/log-in HTTP/1.1 Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 35 Content-Type: application/json Host: localhost:8000 User-Agent: HTTPie/0.9.8 { "name": "aaa", "password": "aaaa" } HTTP/1.1 200 OK Content-Length: 113 Content-Type: application/json Date: Sat, 15 Feb 2020 06:34:22 GMT Server: WSGIServer/0.2 CPython/3.6.9 X-Content-Type-Options: nosniff X-Frame-Options: DENY { "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiYWFhIn0.S1kF79l09KCeYHst2xFsvz7i3Pivz0BmOONpZvkWqcg"
로그인에 성공하면 200ok메세지와 함께 token이 json으로 반환된다
Accept: application/json, */* Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 34 Content-Type: application/json Host: localhost:8000 User-Agent: HTTPie/0.9.8 { "name": "aaa", "password": "aaa" } HTTP/1.1 401 Unauthorized Content-Length: 0 Content-Type: text/html; charset=utf-8 Date: Sat, 15 Feb 2020 06:36:24 GMT Server: WSGIServer/0.2 CPython/3.6.9 X-Content-Type-Options: nosniff X-Frame-Options: DENY
실패 시 위와같이 401 unauthorized를 반환한다