※ 이 포스트는 <Django로 쉽게 배우는 배프의 오지랖 파이썬 웹 프로그래밍>을 참고하여 작성하였습니다.
1. 회원가입 양식 폼 작성
# accounts/forms.py
from django.contrib.auth.models import User
from django import forms
class RegisterForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat Password', widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email']
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords not matched!')
return cd['password2']
- RegisterForm : forms.ModelForm을 상속받으며, 모델이 있고 그에 대한 자료를 입력받고 싶을 때 사용
- Meta 클래스 : 기존에 있는 모델의 입력 폼을 쉽게 만들고자 할 때 사용, model을 통해 사용할 모델을 설정하고 fields를 통해 입력받을 필드들을 지정
- password의 경우는 별도의 widger 옵션을 사용해 password 속성의 input 태그를 사용하기 위해 클래스 변수로 따로 지정
- clean_password2 메서드는 각 필드의 clean 메서드가 호출된 후에 호출되는 메서드. 특별한 유효성 검사나 조작을 하고 싶을 때 만들어서 사용함. password와 password2가 같은지 비교하는 코드 용도
- clean_ 필드명 형태의 메서드에서 해당 필드의 값을 사용할 때는 꼭 cleaned_deta에서 필드 값을 찾아서 사용해야 함. 이 값은 이전 단계까지 기본 유효성 검사와 같은 처리를 마친 값이기 때문
2. 함수형 뷰 작성
# accounts/views.py
from django.shortcuts import render
from .forms import RegisterForm
def register(request):
if request.method == 'POST':
user_form = RegisterForm(request.POST)
if user_form.is_valid():
new_user = user_form.save(commit=False)
new_user.set_password(user_form.cleaned_data['password'])
new_user.save()
return render(request, 'registration/register_done.html', {'new_user':new_user})
else:
user_form = RegisterForm()
return render(request, 'registration/register.html', {'form':user_form})
이하는 코드 설명 주석
# accounts/views.py
from django.shortcuts import render
from .forms import RegisterForm
def register(request):
if request.method == 'POST':
# 회원 가입 정보가 서버로 전달되었는가? 확인
user_form = RegisterForm(request.POST)
# 정보가 서버로 전달되었다면, RegisterForm을 통해 유효성 검사를 수행
if user_form.is_valid():
new_user = user_form.save(commit=False)
# 폼 객체에 지정된 모델을 확인하고, 메모리 상에 모델의 객체를 만든다. (commit=False이므로 데이터베이스에 저장하는 것은 아님)
new_user.set_password(user_form.cleaned_data['password'])
# 비밀번호 지정
new_user.save()
# 실제로 데이터베이스에 저장
return render(request, 'registration/register_done.html', {'new_user':new_user})
# 회원가입이 완료되면 register_done이라는 템플릿을 렌더링해 보여줌
else:
# HTTP 메서드가 POST가 아니라면, 자료를 전달받은 상태가 아니므로
user_form = RegisterForm()
# 비어 있는 RegisterForm 객체를 만들고
return render(request, 'registration/register.html', {'form':user_form})
# register 템플릿을 렌더링해 보여줌
3. URL 연결
# accounts/urls.py
from django.urls import path
from django.contrib.auth import views as auth_view
# 추가한 코드
from .views import register
# 추가한 코드 끝
urlpatterns = [
path('login/', auth_view.LoginView.as_view(), name='login'),
path('logout/', auth_view.LogoutView.as_view(template_name='registration/logout.html'), name='logout'),
# 추가한 코드
path('register/', register, name='register'),
# 추가한 코드 끝
]
4. 회원가입 페이지 템플릿 작성
<!-- accounts/templates/registration/register.html -->
{% extends 'base.html' %}
{% block title %}회원가입{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8 panel panel-default">
<div class="alert alert-info">정보를 입력하세요.</div>
<form action="" method="post">
{{form.as_p}}
{% csrf_token %}
<input class="btn btn-primary" type="submit" value="Register">
</form>
</div>
<div class="col-md-2"></div>
</div>
{% endblock %}
5. 회원가입 완료 페이지 템플릿 작성
<!-- accounts/templates/registration/register_done.html -->
{% extends 'base.html' %}
{% block title %}회원가입 완료{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8 panel panel-default">
<div class="alert alert-info">가입이 완료되었습니다. 환영합니다, {{new_user.username}}님!</div>
<a class="btn btn-info" href="/fst">메인으로</a>
</form>
</div>
<div class="col-md-2"></div>
</div>
{% endblock %}
6. base.html에 회원가입 링크 연결
<!-- templates/base.html -->
...
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
{% if user.is_authenticated %}
<li class="nav-item"><a href="{% url 'logout' %}" class="nav-link">로그아웃</a></li>
{% else %}
<li class="nav-item"><a href="{% url 'login' %}" class="nav-link">로그인</a></li>
<!-- 추가한 코드 -->
<li class="nav-item"><a href="{% url 'register' %}" class="nav-link">회원가입</a></li>
<!-- 추가한 코드 끝 -->
{% endif %}
</ul>
</div>
...
7. 서버 실행하여 결과 확인
$ python manage.py runserver




8. 관리자 계정으로 로그인하여 유저 정보 확인



회원가입이 완료되었다.
번외. DB 클라이언트 툴로 테이블 데이터 확인 + Django의 암호화?
이번엔 TablePlus에 접속하여 DB 데이터들을 확인해보자.
현재 공공데이터를 저장하는 데에 postgreSQL DB를 사용하고 있으므로
User의 정보들 또한 당연히 postgerSQL DB에 저장되어 있다.

DB를 보면서 내가 가장 신기했던 건 password 부분이었는데,

Django는 기본적으로 암호화 알고리즘(PBKDF2)을 제공하고 있어서
사용자가 별도로 암호화 처리를 하지 않아도 된다.
이게 굉장히 편리했다.
그런데 Django의 암호화와 관련해서 검색해본 결과,
기본 제공 암호화 함수 보다는
차세대 암호화 알고리즘인 Argon2 라이브러리를 받아 사용하는 것을 권장한다고 한다.
공식 문서에도 이렇게 쓰여있다.
(https://docs.djangoproject.com/en/4.1/topics/auth/passwords/ 참고)
| Argon2 is the winner of the 2015 Password Hashing Competition, a community organized open competition to select a next generation hashing algorithm. It’s designed not to be easier to compute on custom hardware than it is to compute on an ordinary CPU. Argon2 is not the default for Django because it requires a third-party library. The Password Hashing Competition panel, however, recommends immediate use of Argon2 rather than the other algorithms supported by Django. |
요약하면 Argon2이 암호 해싱 경쟁에서 우승했고 Django 내의 다른 암호화 알고리즘보다 좋으니 사용하는걸 권고한다는 이야기.
(Django 공식 사이트에서 대놓고 이거 써라! 라고 하진 않고 암호 해싱 경쟁 패널들이 추천한다고 간접적으로 쓰여있다.)
다음에는 Agron2 라이브러리를 설치해서 암호화를 적용해봐야겠다.
'Django' 카테고리의 다른 글
| Django 회원가입 후 자동 로그인 (0) | 2022.12.07 |
|---|---|
| Django Argon2 암호화 알고리즘 적용하기 (0) | 2022.12.06 |
| Django 로그인, 로그아웃 기능 추가하기 (0) | 2022.12.01 |
| postgreSQL 데이터 프론트에 띄우기 (0) | 2022.12.01 |
| Django와 postgreSQL 연동하기 (0) | 2022.11.30 |
댓글