# models.py
from django.db import models
class User(models.Model):
name = models.CharField(max_length=45)
email = models.CharField(max_length=300)
password = models.CharField(max_length=400)
phone_number = models.CharField(max_length=45)
birthday = models.DateField()
class Meta:
db_table = 'users'
이메일과 패스워드는 문자와 숫자를 다사용하기에 CharField
를 적용하였고 최대길이를 넉넉하게 설정하였다. 이메일은 그렇다쳐도 패스워드의 최대길이를 길게 한 이유는 나중에 암호화 시킬 경우 문자열의 길이가 길어지기 때문이다.
전화번호의 경우 IntegerField
를 설정할 경우 0
이 맨 앞에 오게되면 010
의 경우 10
으로 표시되어 0
의 숫자가 나오지 않기 때문에 CharField
를 적용하였고 생일의 경우 날짜에 맞는 필드가 있기에 DateField
를 적용시켰다.
# views.py
class SignupView(View):
def post(self, request):
try:
data = json.loads(request.body)
password = data['password']
hashed_password = bcrypt.hashpw(password.encode('utf-8'),bcrypt.gensalt()).decode('utf-8')
# 이메일의 형식에 맞게 적용하는지 확인
if not re.search(r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w+[.]?\w{2,3}$',(data['email'])):
return JsonResponse({'message':'INVALID_EMAIL_FORMAT'}, status=400)
# 비밀번호 8자리 이상 숫자와 특수문자 사용
if not re.search(r'[A-Za-z0-9!@##$%^&+=]{8,25}',(data['password'])):
return JsonResponse({'message':'CHARACTER_SHORT'}, status=400)
# 중복된 이메일이 있는지 확인
if User.objects.filter(email=data['email']).exists():
return JsonResponse({'massage':'INVALID_EMAIL'}, status=400)
User.objects.create(
name = data['name'],
email = data['email'],
password = hashed_password,
phone_number = data['phone_number'],
birthday = data['birthday'],
)
return JsonResponse({'message':'SUCCESS'}, status=201)
except KeyError: # 키값의 오타가 있을 경우에 키에러를 발생하게함
return JsonResponse({'message':'KEY_ERROR'}, status=400)
hashed_password
는 bcrypt
라는 라이브러리를 사용하여 암호해주었다는 변수를 주었고 마지막 decode('utf-8')
를 사용한 것은 DB
에 저장이 될 때는 string
타입으로 저장이 되어야하기 때문이다.
아직 정규 표현식은 정확하게 이해하지 못하여 구글링을 하여 사용되는 방식을 카피해왔다. 정규표현식의 경우 더욱 공부해야할 것 중 하나로 계획할 것이다. 정규표현식의 re
를 사용하여 적용시킬때는match
와 search
가 있는데 두 방식의 차이점은 match
의 경우 문자열의 처음부터 정규식과 매치되는지 조사하고 search
의 경우 문자열 전체를 검색하여 정규식과 매치되는지 조사한다. 아직 정확히 이해를 하지못한 정규식을 사용하였기에 search
를 사용하였다.
둘의 같은점은 정규식에 적합하면 match
객체를 돌려주고 그렇지 않으면 None
을 돌려준다.
난 위의 코드에서 if not
으로 정규식표현에 부합하지않으면 예외처리된 메세지가 반환되게 설정을 하였다.
class LoginView(View):
def post(self, request):
try:
data = json.loads(request.body)
#로그인시 회원가입된 이메일이 없는경우
if not User.objects.filter(email=data['email']).exists():
return JsonResponse({'message':'INVALID_USER'}, status=401)
#존재하는 이메일이면 가져오기
user = User.objects.get(email = data['email'])
#암호화된 비밀번호를 다시 부호화하여 회원가입된 이메일의 비밀번호와 맞는지 확인
if not bcrypt.checkpw(data['password'].encode('utf-8'), user.password.encode('utf-8')):
return JsonResponse({'message':'INVALID_USER'}, status=401)
#회원가입된 이메일과 패스워드가 맞다면 토큰을 발행
access_token = jwt.encode({'id' : user.id}, SECRET_KEY, algorithm = 'HS256')
return JsonResponse({'token' : access_token}, status=200)
except KeyError:
return JsonResponse({'message':'KEY_ERROR'}, status=400)
http
는 단기기억능력을 가지고있는데 이를 보안하기위해 로그인을 했을시 계속 로그인 하지않기 위해 로그인되었다는 증표인 토큰
을 부여한다. 토큰의 생성은 Json Web Token
즉 약어로 jwt
라는 라이브러리를 사용한다. 각 유저의 중복되지 않는 고유번호인 id
를 부여해서 사용한다. 로그인 상태에서만 가능한 기능들이 있다. 예를들어 게시물을 올린다던가 댓글을 남긴다거나 수정하고 삭제하나하는 경우 로그인이 된상태에서만 가능하다 이럴때는 로그인이 되었다는 증표인 토큰
이 필요한다. 개발을하여 기능을 만들때마다 코드를 작성해주기에는 번거롭거나 실수로 작성을 못하는경우가 있기에 데코레이터!!!
라는 기능을 사용하면된다. 데코레이터
는 따로 블로그를 작성을 할 예정이다.