SlideShare a Scribd company logo
1 of 19
Download to read offline
Gnuboard to Django
Series #01
(그누보드와장고가 한유저DB를사용하기)
2016. 09. 28.
이준범(jun@beomi.net)
사건의발단
(이라쓰고 삽질의시작이라읽는다)
구상
1. 현재 웹 서비스 하나가 그누보드로 돌아가고있다.
2. 새로운 서비스를 만들고 싶다! 근데 PHP는 싫어
3. 그리고 싸이클럽에서 갈아엎은지도 얼마 되지 않았는데..
4. 또 새롭게 가입하게 만들면 유저의 피로도는?
--> Soultions
1. 그냥 다 갈아엎자.
2. 포기하면.. 편해
3. Django가 기존 DB를 사용할 수 있진 않을까? --> 선택!
Django가 기존DB를
사용하게 하자
어떻게 해야하나(난관들)
1. 기존 DB구조에 맞게 장고가 동작하게 하려면?
수백개의 DB 스키마를 직접 짤수는 도저히 없다.
2. 제일 큰 문제: 유저 로그인
장고에서 기본으로 제공해주는 암호화 방식이 아니다!
(그누보드는 MySQL의 password()함수를 이용한다)
3. 사용자가 눈치채지 못하고 기존 서비스와
새로운 서비스가 연속적으로 이어져야 한다.
Solutions
1. 어떻게 장고가 기존 DB를 사용하게 할까?
장고에는 자동으로 DB(default로 설정된)의
스키마를 가져오게 할 수 있다!
$ python manage.py inspectdb > legacydb.py
inspectdb를 사용할 경우 자동으로
장고에서 사용할 수 있는 모델단을 만들어 준다.
단, Relation와 위치관계는 수동으로 정렬해줘야 한다.
inspectdb는 기본적으로 default로 설정된 DB를 체크
따라서 검사할 DB를 미리 settings.py에 등록해두자.
Solutions
2. 어떻게 장고가 그누보드의 User 모델을 사용하게 할까?
필요한 것
1번에서 만든 DB Model
이 안에 많은 추가 설정이 필요하다.
Custom User매니저(BaseUserManage를 상속받은)
Custom AuthBackend
만들어봅시다
InspectDB로만든
models.py와G5Member [source]
# 공간의 제약으로 일부 모델을 생략했습니다. 원본은 source를 참고해주세요
class G5Member(AbstractBaseUser):
mb_no = models.AutoField(primary_key=True)
email = models.CharField(max_length=255, db_column='mb_email
mb_level = models.IntegerField()
mb_id = models.CharField(unique=True, max_length=20)
password = models.CharField(max_length=255, db_column='mb_pa
last_login = models.DateTimeField(db_column='mb_today_login'
username = models.CharField(max_length=255, db_column='mb_ni
USERNAME_FIELD = 'mb_id' #unique=True여야 합니다
REQUIRED_FIELDS = ['mb_level','email','username']
def get_username(self):
return self.mb_id
def has_perm(self, perm, obj=None):
return self.is_superuser()
def has_module_perms(self, app_label):
return self.is_superuser()
def get_short_name(self):
return self.username
def is_superuser(self):
if self.mb_level == 10: # 그누보드는 Level10이 관리자
return True
else:
return False
def is_staff(self):
if self.mb_level == 10: # 그누보드는 Level10이 관리자
return True
else:
return False
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, username, email, password, **extr
"""
Creates and saves a User with the given username, em
"""
if not username:
raise ValueError('The given username must be set
email = self.normalize_email(email)
username = self.model.normalize_username(username)
user = self.model(email=email, username=username)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username, email=None, password=Non
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(username, email, password,
def create_superuser(self, username, email, password, **
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=T
if extra_fields.get('is_superuser') is not True
raise ValueError('Superuser must have is_superus
return self._create_user(username, email, password,
objects = UserManager()
class Meta:
managed = False
db_table = 'g5_member'
Point
최대한 그누보드 DB이름을 사용
Django AUTH_USER_MODEL에서 원하는 User
Attribute를 모두 추가해두기
USERNAME_FIELD는 장고가 Unique한 username
으로 관리하는 DB 컬럼을 지정
password필드의 이름은 바꾸지 못한다.
따라서 db_column='컬럼명'으로
기존 DB의 암호 컬럼에 연결해야한다.
위 코드에 쓰여진 method/attribute는
장고 BaseUserManager가 필요로 하는 최소.
Custom Auth 만들기[source]
from django.utils.crypto import constant_time_compare
import hashlib
from .models import G5Member as User
class MyUserAuthBackend(object):
def check_legacy_password(self, db_password, supplied_passwo
return constant_time_compare('*'+ hashlib.sha1(hashlib.s
def authenticate(self, username=None, password=None):
try:
user = User.objects.get(mb_id=username)
if '$' not in user.password:
if self.check_legacy_password(user.password, pas
return user
else:
return None
else:
if user.check_password(password):
return user
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
이와 같이 작성해야한다.
이 파일의 MyUserAuthBackend를 장고 프로젝트의
settings파일에 등록해주어야 한다.
CustomAuth 등록하기[source]
# ...somesettings..
INSTALLED_APPS = [
# ...
'auth_app',
# ...
]
AUTHENTICATION_BACKENDS = ['auth_app.auth.MyUserAuthBackend'
AUTH_USER_MODEL = (
'auth_app.G5Member'
)
# othersettings...
정리
정리
이와같이 유저모델을 정의해준다면 장고에서 그누보드에서
사용하는 유저를 함께 사용할 수 있다.
그누보드를 유지하고 그누보드쪽에서 회원 생성을 관리하고
뷰와 다른 로직들을 장고에서 사용할 수 있다.
Happy Coding with Django!
Source 정리
장고 앱중하나에서models.py
위models.py와함께하는auth.py
장고 프로젝트settings.py

More Related Content

What's hot

uEngineBPM 개발자교육 2 커스텀액티비티
uEngineBPM 개발자교육 2 커스텀액티비티uEngineBPM 개발자교육 2 커스텀액티비티
uEngineBPM 개발자교육 2 커스텀액티비티flowcontrol
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Kyoung Up Jung
 
Python 웹 프로그래밍
Python 웹 프로그래밍Python 웹 프로그래밍
Python 웹 프로그래밍용 최
 
유엔진 BPM 커스터마이징 개발 방법
유엔진 BPM 커스터마이징 개발 방법유엔진 BPM 커스터마이징 개발 방법
유엔진 BPM 커스터마이징 개발 방법uEngine Solutions
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Kyoung Up Jung
 
Nodejs를 이용한 개발
Nodejs를 이용한 개발Nodejs를 이용한 개발
Nodejs를 이용한 개발WebFrameworks
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storageJinKyoungHeo
 
코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기Yong Hoon Kim
 
[D2CAMPUS]JavaScript 다시 시작하기
[D2CAMPUS]JavaScript 다시 시작하기[D2CAMPUS]JavaScript 다시 시작하기
[D2CAMPUS]JavaScript 다시 시작하기NAVER D2
 
테스트가 뭐예요?
테스트가 뭐예요?테스트가 뭐예요?
테스트가 뭐예요?Kyoung Up Jung
 
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기Kwangyoun Jung
 
5-3. html5 device access
5-3. html5 device access5-3. html5 device access
5-3. html5 device accessJinKyoungHeo
 
부동산 텔레그램봇 사내공유 @Tech
부동산 텔레그램봇 사내공유 @Tech부동산 텔레그램봇 사내공유 @Tech
부동산 텔레그램봇 사내공유 @TechHoChul Shin
 
처음배우는 자바스크립트, 제이쿼리 #2
처음배우는 자바스크립트, 제이쿼리 #2처음배우는 자바스크립트, 제이쿼리 #2
처음배우는 자바스크립트, 제이쿼리 #2성일 한
 
Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기영우 박
 
간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기Kyoung Up Jung
 
[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)
[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)
[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)YoungSu Son
 

What's hot (19)

uEngineBPM 개발자교육 2 커스텀액티비티
uEngineBPM 개발자교육 2 커스텀액티비티uEngineBPM 개발자교육 2 커스텀액티비티
uEngineBPM 개발자교육 2 커스텀액티비티
 
Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.Django, 저는 이렇게 씁니다.
Django, 저는 이렇게 씁니다.
 
Meteor2015 codelab
Meteor2015 codelab Meteor2015 codelab
Meteor2015 codelab
 
Python 웹 프로그래밍
Python 웹 프로그래밍Python 웹 프로그래밍
Python 웹 프로그래밍
 
유엔진 BPM 커스터마이징 개발 방법
유엔진 BPM 커스터마이징 개발 방법유엔진 BPM 커스터마이징 개발 방법
유엔진 BPM 커스터마이징 개발 방법
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기
 
Nodejs를 이용한 개발
Nodejs를 이용한 개발Nodejs를 이용한 개발
Nodejs를 이용한 개발
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storage
 
코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기코드리뷰 짝 매칭 프로그램 구현기
코드리뷰 짝 매칭 프로그램 구현기
 
[D2CAMPUS]JavaScript 다시 시작하기
[D2CAMPUS]JavaScript 다시 시작하기[D2CAMPUS]JavaScript 다시 시작하기
[D2CAMPUS]JavaScript 다시 시작하기
 
테스트가 뭐예요?
테스트가 뭐예요?테스트가 뭐예요?
테스트가 뭐예요?
 
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
QnA Blog Using Django - 회원가임/로그인폼, Post, 글보기
 
5-3. html5 device access
5-3. html5 device access5-3. html5 device access
5-3. html5 device access
 
부동산 텔레그램봇 사내공유 @Tech
부동산 텔레그램봇 사내공유 @Tech부동산 텔레그램봇 사내공유 @Tech
부동산 텔레그램봇 사내공유 @Tech
 
처음배우는 자바스크립트, 제이쿼리 #2
처음배우는 자바스크립트, 제이쿼리 #2처음배우는 자바스크립트, 제이쿼리 #2
처음배우는 자바스크립트, 제이쿼리 #2
 
Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기Django admin site 커스텀하여 적극적으로 활용하기
Django admin site 커스텀하여 적극적으로 활용하기
 
간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기간단한 블로그를 만들며 Django 이해하기
간단한 블로그를 만들며 Django 이해하기
 
[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)
[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)
[NEXT] Android 개발 경험 프로젝트 2일차 (Intent, ListView, Adapter)
 
Web_05_ jQuery
Web_05_ jQueryWeb_05_ jQuery
Web_05_ jQuery
 

Gnuboard to Django Series #01

  • 1. Gnuboard to Django Series #01 (그누보드와장고가 한유저DB를사용하기) 2016. 09. 28. 이준범(jun@beomi.net)
  • 3. 구상 1. 현재 웹 서비스 하나가 그누보드로 돌아가고있다. 2. 새로운 서비스를 만들고 싶다! 근데 PHP는 싫어 3. 그리고 싸이클럽에서 갈아엎은지도 얼마 되지 않았는데.. 4. 또 새롭게 가입하게 만들면 유저의 피로도는? --> Soultions 1. 그냥 다 갈아엎자. 2. 포기하면.. 편해 3. Django가 기존 DB를 사용할 수 있진 않을까? --> 선택!
  • 5. 어떻게 해야하나(난관들) 1. 기존 DB구조에 맞게 장고가 동작하게 하려면? 수백개의 DB 스키마를 직접 짤수는 도저히 없다. 2. 제일 큰 문제: 유저 로그인 장고에서 기본으로 제공해주는 암호화 방식이 아니다! (그누보드는 MySQL의 password()함수를 이용한다) 3. 사용자가 눈치채지 못하고 기존 서비스와 새로운 서비스가 연속적으로 이어져야 한다.
  • 6. Solutions 1. 어떻게 장고가 기존 DB를 사용하게 할까? 장고에는 자동으로 DB(default로 설정된)의 스키마를 가져오게 할 수 있다! $ python manage.py inspectdb > legacydb.py inspectdb를 사용할 경우 자동으로 장고에서 사용할 수 있는 모델단을 만들어 준다. 단, Relation와 위치관계는 수동으로 정렬해줘야 한다. inspectdb는 기본적으로 default로 설정된 DB를 체크 따라서 검사할 DB를 미리 settings.py에 등록해두자.
  • 7. Solutions 2. 어떻게 장고가 그누보드의 User 모델을 사용하게 할까? 필요한 것 1번에서 만든 DB Model 이 안에 많은 추가 설정이 필요하다. Custom User매니저(BaseUserManage를 상속받은) Custom AuthBackend
  • 9. InspectDB로만든 models.py와G5Member [source] # 공간의 제약으로 일부 모델을 생략했습니다. 원본은 source를 참고해주세요 class G5Member(AbstractBaseUser): mb_no = models.AutoField(primary_key=True) email = models.CharField(max_length=255, db_column='mb_email mb_level = models.IntegerField() mb_id = models.CharField(unique=True, max_length=20) password = models.CharField(max_length=255, db_column='mb_pa last_login = models.DateTimeField(db_column='mb_today_login' username = models.CharField(max_length=255, db_column='mb_ni USERNAME_FIELD = 'mb_id' #unique=True여야 합니다 REQUIRED_FIELDS = ['mb_level','email','username']
  • 10. def get_username(self): return self.mb_id def has_perm(self, perm, obj=None): return self.is_superuser() def has_module_perms(self, app_label): return self.is_superuser() def get_short_name(self): return self.username def is_superuser(self): if self.mb_level == 10: # 그누보드는 Level10이 관리자 return True else: return False def is_staff(self): if self.mb_level == 10: # 그누보드는 Level10이 관리자 return True else: return False
  • 11. class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self, username, email, password, **extr """ Creates and saves a User with the given username, em """ if not username: raise ValueError('The given username must be set email = self.normalize_email(email) username = self.model.normalize_username(username) user = self.model(email=email, username=username) user.set_password(password) user.save(using=self._db) return user def create_user(self, username, email=None, password=Non extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) return self._create_user(username, email, password,
  • 12. def create_superuser(self, username, email, password, ** extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) if extra_fields.get('is_staff') is not True: raise ValueError('Superuser must have is_staff=T if extra_fields.get('is_superuser') is not True raise ValueError('Superuser must have is_superus return self._create_user(username, email, password, objects = UserManager() class Meta: managed = False db_table = 'g5_member'
  • 13. Point 최대한 그누보드 DB이름을 사용 Django AUTH_USER_MODEL에서 원하는 User Attribute를 모두 추가해두기 USERNAME_FIELD는 장고가 Unique한 username 으로 관리하는 DB 컬럼을 지정 password필드의 이름은 바꾸지 못한다. 따라서 db_column='컬럼명'으로 기존 DB의 암호 컬럼에 연결해야한다. 위 코드에 쓰여진 method/attribute는 장고 BaseUserManager가 필요로 하는 최소.
  • 14. Custom Auth 만들기[source] from django.utils.crypto import constant_time_compare import hashlib from .models import G5Member as User class MyUserAuthBackend(object): def check_legacy_password(self, db_password, supplied_passwo return constant_time_compare('*'+ hashlib.sha1(hashlib.s def authenticate(self, username=None, password=None): try: user = User.objects.get(mb_id=username) if '$' not in user.password: if self.check_legacy_password(user.password, pas return user else: return None else: if user.check_password(password): return user except User.DoesNotExist: return None
  • 15. def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None 이와 같이 작성해야한다. 이 파일의 MyUserAuthBackend를 장고 프로젝트의 settings파일에 등록해주어야 한다.
  • 16. CustomAuth 등록하기[source] # ...somesettings.. INSTALLED_APPS = [ # ... 'auth_app', # ... ] AUTHENTICATION_BACKENDS = ['auth_app.auth.MyUserAuthBackend' AUTH_USER_MODEL = ( 'auth_app.G5Member' ) # othersettings...
  • 18. 정리 이와같이 유저모델을 정의해준다면 장고에서 그누보드에서 사용하는 유저를 함께 사용할 수 있다. 그누보드를 유지하고 그누보드쪽에서 회원 생성을 관리하고 뷰와 다른 로직들을 장고에서 사용할 수 있다. Happy Coding with Django!