
기존의 모델은 클래스 상속 없이 작성됐다.
class Account(models.Model):
pid = models.CharField(max_length=30, null=True)
pwd = models.CharField(max_length=30, null=True)
created = models.DateTimeField(null=True, auto_now_add=True)
def __str__(self):
return "pid: "+self.pid
class Meta:
ordering = ['created']
계정(pid)과 비밀번호(pwd) 정보만을 받아서 저장했고, DateTimeField를 사용하여 생성날짜(created)를 알 수 있도록 했다.
$ python manage.py shell으로 ORM을 사용할 때, 객체가 저장하고 있는 정보를 알리기 위해 __str__함수를 정의해줬다.
정렬 순서(ordering)은 생성순(created)으로 정해줬다.
하지만 이렇게 해놓고 회원가입 기능을 사용하려고 할 때는 @csrf_exempt를 붙여줘야 했다.
이걸 붙여주지 않으면 아래와 같은 결과창을 볼 수 있다.

Forbidden(403) CSRF verification failed. Request aborted.
CSRF: Cross Site Request Forgery
통상적인 방법으로 인증을 받은 사용자가 가진 권한을 공격자가 이용하여 서버에 변조된 요청을 보내는 공격방식.
이를 막기 위해 django에서는 CSRF에 대응하는 기능을 제공한다.
헌데 내 경우에 이 기능에 대한 예외를 설정하지 않으면(@csrf_exempt를 데코레이팅하지 않으면) Forbidden을 구경할 수밖에 없었다.
기능을 사용하기 위해 보안벽을 떼놓는다는 게, 지금 다시 생각해보면 정말 말이 안 되는 짓이다.
하지만 프로젝트 진행 초기에는 그냥 앱에서 들어오는 정보들을 받아서 데이터베이스에 넣을 수 있다는 사실에 신명이 나서 @csrf_exempt를 온통 발라놨다.
그리고 후반부가 되어서야
'이야 이거 진짜 어떡하나' 이런 생각이 들었다.
django에서 제공하는 보안 기능 속에서 사용자에 대한 인증(Auth)이 이뤄지고 해당 사용자가 가질 권한(permission)에 대해서도 생각해봐야 했다.
그래서 AbstractBaseUser 또는 AbstractUser를 상속해서 써야겠단 생각을 했다.
특징
언제 사용?
이 클래스를 상속하면 단 두개의 필드를 받게 된다.
스키마에 큰 영향을 준다는 것이 아마도 $ migrate 수행 시, 기존에 생성되어 있던 auth_user 그룹과 충돌이 일어나고 이걸 해결하기 위한 효과적인 방법이 없어서가 아닐까 싶다.
특징
settings.py에 AUTH_USER_MODEL = '앱이름.유저모델이름'과 같이 참조 작업이 필요하다.❗️
'앱이름.유저모델이름'을 입력할 때 반드시 따옴표로 묶어줘야 한다
언제 사용?
읽어보면 AbstractUser를 쓰는게 상당히 좋아보였기에 이걸 써봤다.
(참고자료는 페이지 마지막에 링크)
class User(AbstractUser, PermissionsMixin):
class Meta:
ordering = ['date_joined']
# username = models.CharField()
# password = models.CharField()
# last_login = models.DateTimeField(blank=True, null=True)
# first_name = models.CharField(max_length=30, blank=True)
# last_name = models.CharField(max_length=150, blank=True)
# email = models.EmailField(blank=True)
# is_staff = models.BooleanField()
# is_active = models.BooleanField()
# date_joined = models.DateTimeField()
# is_superuser = models.BooleanField()
#주석처리된 부분이 AbstractUser 클래스를 상속했을 때 기본적으로 갖게 되는 필드들이다.
일단 난 username과 password만 필요했기 때문에 추가적으로 모델 정보를 작성하진 않았다. 그리고 username과 password라는 명칭을 바꾸기보단 안정적으로 그대로 사용하는 것을 택했다.
잊지 말아야 할 것은 위의 설명글에서처럼 settings.py에 AUTH_USER_MODEL을 추가해주는 것이다.
나는 user앱의 models.py에 User라는 이름으로 AbstractUser를 상속했으므로 AUTH_USER_MODEL = 'user.User'라고 적어줬다.
글로 구구절절 적어놔서 길게 보일 수 있지만
1. AbstractUser 상속
2. settings.py에 AUTH_USER_MODEL='앱이름.모델이름' 알려주기
이게 끝이다. 정말 간단하다.
이렇게'만' 해주는 것으로도 @csrf_exempt를 남발하는 참사를 막을 수 있다.

@csrf_exempt는 이제 없다.😎 기능도 정상적으로 작동한다.
@api_view를 사용해보았다. @api_view를 써서 해당 view가 어떻게 작동하고 있는지 어떤 옵션을 가지고 있는지를 볼 수도 있고 해당 기능에 대한 테스트 작업도 해볼 수 있다!
다른 모델은 기존에 사용하던 방식과 동일하게 모델을 작성해줬다. 예를 들면 아래와 같은 코드다.
# 스쿼트 운동 관련 모델
class Squat(models.Model):
username = models.CharField(max_length=25)
count = models.FloatField(max_length=255)
sum_times = models.IntegerField(null=True)
sum_count = models.IntegerField(null=True)
times = models.FloatField(max_length=255)
title = models.CharField(max_length=255, null=True)
day = models.CharField(max_length=255, null=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "Count:"+str(self.count)+" Time:"+str(self.times)+" Date:"+self.day
class Meta:
ordering = ['created']
로그인 시에 필요한 계정명과 동일한 username으로 column이름을 사용했다. 다만 필드를 CharField로 설정하여 특정 계정의 기록을 불러올 때 사용할 수 있도록 해놓았다.
이 부분은 아마 permission을 설정할 때 따로 바꿔야할 수도 있겠다. 혹은 전체 DB 구성을 다시 작성해할 수도 있겠단 생각이 든다.😓
이렇게 해두면 아무나 권한 없이 특정 사용자의 이름으로 기록을 등록할 수 있게 되어버린다.
위 User모델에서 볼 수 있듯이 permissionMixin을 사용해보기 위해 상속해놓았다.
model에 대한 다음 공부 주제는 권한(permission)을 현재의 user모델에 연관짓는 것으로 할 것이다.
django user모델의 확장
[DJango] AbstractBaseUser vs AbstractUser 비교하기
Spring Security_CSRF Token의 개념과 사용 방법
Django Rest Framework 활용하기 2 - @api_view
파이썬 데코레이터란? 사용방법은?