필요한 모듈이 설치되어 있지 않다면 설치합니다.
> pip install bcrypt
> pip install pyjwt
User App의 Views.py
파일에 회원가입을 위한 SignUpView를 아래와 같이 작성합니다.
request 요청을 data 변수에 담기
패스워드를 bcrypt
로 암호화하여 hashed_password
로 담기
(str인 자료형을 encode하여 bytes로 형변환함)
request 전송된 name
, email
과 hashed_password
를 객체를 생성하고 저장
(bytes을 decode하여 str으로 형변환해 DB에 저장)
200 OK 메시지 JSON으로 리턴
(이하 예외 처리는 생략함)
class SignUpView(View):
def post(self, request):
data = json.loads(request.body)
# name, email, password 미입력시 처리 + name/email 이미 존재할 때 처리
try:
hashed_password= bcrypt.hashpw(data['password'].encode('utf-8'), bcrypt.gensalt())
User(
name = data['name'],
email = data['email'],
password = hashed_password.decode('utf-8')
).save()
return JsonResponse({'message':'SUCCESS'}, status=200)
# 이하 예외 처리는 생략함
❯ http -v http://127.0.0.1:8000/user/ name=young email=young@young.com password=1234
POST /user/ HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 65
Content-Type: application/json
Host: 127.0.0.1:8000
User-Agent: HTTPie/2.1.0
{
"email": "young@young.com",
"name": "young",
"password": "1234"
}
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Date: Wed, 20 May 2020 03:00:49 GMT
Server: WSGIServer/0.2 CPython/3.7.7
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"message": "SUCCESS"
}
User App의 Views.py
파일에 로그인을 위한 LoginView를 아래와 같이 작성합니다.
request 요청을 data
변수에 담기
name(사용자ID), password 미입력 시 400 JSON 리턴
data['name']
과 동일한 name을 가진 객체가 존재할 경우 아래 구문 실행
data['password']
와 user.password
를 bcypt.checkpw
메소드로 확인 -> True일 경우 아래 구문 실행
(2개 데이터는 encode하여 bytes로 형변환한 뒤 비교)
jwt
로 access_token을 만들어 token
변수에 담기
token
변수를 {'token' : token.decode('utf-8')}
JSON에 담아서 전달
class LoginView(View):
def post(self, request):
data = json.loads(request.body)
checked_name = data.get('name', None)
# 데이터 안 넘어올 때 에러 방지 위해 없애려 None 처리
checked_password = data.get('password', None)
# name, pass 미입력, name 존재하지 않을 시 처리 후 진행
try:
if checked_name == '':
return JsonResponse({"message" : "Please enter ID"}, status=400)
elif checked_password == '':
return JsonResponse({"message" : "Please enter password"}, status=400)
elif User.objects.filter(name=checked_name).exists():
user = User.objects.get(name=checked_name)
if bcrypt.checkpw(checked_password.encode('utf-8'), user.password.encode('utf-8')):
token = jwt.encode({'user_id': user.id}, 'secret', algorithm='HS256')
return JsonResponse({'token' : token.decode('utf-8')}, status=200)
return JsonResponse({"message" : "INVALID_PASSWORD"}, status=400)
# 이하 예외 처리는 생략
❯ http -v http://127.0.0.1:8000/user/login/ name=young password=1234
POST /user/login/ HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 37
Content-Type: application/json
Host: 127.0.0.1:8000
User-Agent: HTTPie/2.1.0
{
"name": "young",
"password": "1234"
}
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Date: Wed, 20 May 2020 07:44:09 GMT
Server: WSGIServer/0.2 CPython/3.7.7
Vary: Origin
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxMX0.8WeBhffU-wMdOhE4zdS3KJx2XfCYVpAoPNwSjaRovn4"
}