Django 회원가입 & 로그인

Hoontae.KIM·2021년 7월 31일
0
post-thumbnail

Model 작성하기

# 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를 적용시켰다.

View 작성하기

1) SignUp

# 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_passwordbcrypt라는 라이브러리를 사용하여 암호해주었다는 변수를 주었고 마지막 decode('utf-8')를 사용한 것은 DB에 저장이 될 때는 string 타입으로 저장이 되어야하기 때문이다.
아직 정규 표현식은 정확하게 이해하지 못하여 구글링을 하여 사용되는 방식을 카피해왔다. 정규표현식의 경우 더욱 공부해야할 것 중 하나로 계획할 것이다. 정규표현식의 re를 사용하여 적용시킬때는matchsearch가 있는데 두 방식의 차이점은 match의 경우 문자열의 처음부터 정규식과 매치되는지 조사하고 search의 경우 문자열 전체를 검색하여 정규식과 매치되는지 조사한다. 아직 정확히 이해를 하지못한 정규식을 사용하였기에 search를 사용하였다.
둘의 같은점은 정규식에 적합하면 match객체를 돌려주고 그렇지 않으면 None을 돌려준다.
난 위의 코드에서 if not으로 정규식표현에 부합하지않으면 예외처리된 메세지가 반환되게 설정을 하였다.

회원가입성공

이메일형식이 맞지 않을때

비밀번호가 형식에 맞지않을때

중복된 이메일이 있을때

2) Login

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를 부여해서 사용한다. 로그인 상태에서만 가능한 기능들이 있다. 예를들어 게시물을 올린다던가 댓글을 남긴다거나 수정하고 삭제하나하는 경우 로그인이 된상태에서만 가능하다 이럴때는 로그인이 되었다는 증표인 토큰이 필요한다. 개발을하여 기능을 만들때마다 코드를 작성해주기에는 번거롭거나 실수로 작성을 못하는경우가 있기에 데코레이터!!!라는 기능을 사용하면된다. 데코레이터는 따로 블로그를 작성을 할 예정이다.

로그인에 성공하여 토큰이 발행됨

키값인 password를 잘못입력하였을때 발생한 keyerror

profile
💻 STUDY RECORD

0개의 댓글