Django 하이라이트: 사용자 모델 및 인증(1부)
게시 됨: 2022-03-10웹 사이트에는 정적 및 동적의 두 가지 유형이 있습니다. Django는 동적 웹사이트를 개발하기 위한 프레임워크입니다. 정적 웹사이트는 정보만 제공하는 웹사이트이지만 서버에 등록되는 상호작용(단순한 페이지 요청 외에)은 없습니다. 정적 웹 사이트에서 서버는 HTML, CSS 및 JavaScript를 클라이언트에 전송하면 됩니다. 더 많은 기능을 사용하려면 서버가 단순히 페이지를 제공하는 것 이상으로 정보를 저장하고 사용자 상호 작용에 응답하는 동적 웹 사이트가 필요합니다. 동적 사이트를 개발하는 주요 이유 중 하나는 사용자를 인증하고 콘텐츠를 제한하는 것입니다.
정적 웹 사이트를 작성, 배포 및 관리하는 것은 동적 사이트보다 훨씬 쉽고 저렴하며 안전합니다. 따라서 프로젝트에 동적 패러다임의 추가 기능이 필요한 경우에만 동적 웹 사이트를 만들어야 합니다. Django는 기본 제공 구성 요소를 사용하여 동적 사이트를 만드는 프로세스를 단순화하고 간소화합니다. 동적 웹 응용 프로그램의 기본 구성 요소 중 하나인 바퀴와 같은 "사용자 계정" 개체는 재창조하고 싶은 유혹을 받지만 대부분의 용도에는 표준 모양이 적합합니다. Django는 즉시 사용 가능한 강력한 사용자 모델을 제공하며 이 기사에서는 안전하고 직관적인 사용자 인증 흐름을 제공하는 가장 좋은 방법을 살펴보겠습니다.
시리즈의 추가 부품 :
- Django 하이라이트: 템플릿을 사용하면 줄바꿈(2부)
- Django 하이라이트: 모델, 관리자 및 관계형 데이터베이스 활용(3부)
- Django 하이라이트: 정적 자산 및 미디어 파일 랭글링(4부)
설정하기
이 기사의 개념을 실험하기 위해 고유한 Django 응용 프로그램을 만들고 싶다면 디렉터리(가상 환경이 바람직함)를 만들고 다음 명령을 실행할 수 있습니다.
pip install django django-admin startproject PROJECTNAME cd PROJECTNAME python manage.py startapp APPNAME python manage.py migrate python manage.py runserver
첫 번째 Django 프로젝트를 만드는 방법을 찾고 있다면 Django의 자체 웹 사이트에서 훌륭한 프로젝트를 제공합니다. 이 기사에서는 예제 프로젝트를 사용하지 않지만 논의된 개념은 거의 모든 Django 애플리케이션에 적용됩니다.
표준 사용자 모델
기본적으로 사용자 계정의 개념은 액세스 제어와 개인화된 애플리케이션 상태라는 두 가지 이유로 존재합니다. 액세스 제어는 시스템의 리소스가 일부 사용자만 사용할 수 있다는 개념입니다. 개인화된 상태는 애플리케이션의 목적에 크게 의존하지만 개별 사용자에 특정한 설정, 데이터 또는 기타 기록을 포함할 수 있습니다. Django stock User
모델은 두 사용 사례에 대한 합리적인 접근 방식을 제공합니다.
처음에 Django 애플리케이션에는 수퍼유저 계정과 일반 사용자의 두 가지 유형의 사용자가 있습니다. 수퍼유저는 일반 계정의 모든 속성과 권한을 가지고 있지만 Django 관리자 패널에 대한 액세스 권한도 있습니다. 이 패널은 향후 기사에서 자세히 살펴볼 강력한 애플리케이션입니다. 기본적으로 수퍼유저는 다른 사용자 계정을 포함하여 애플리케이션의 모든 데이터를 생성, 편집 또는 삭제할 수 있습니다.
기본적으로 사용자 계정의 개념은 액세스 제어와 개인화된 애플리케이션 상태라는 두 가지 이유로 존재합니다.
"
자신의 Django 애플리케이션에서 수퍼유저를 만들려면 다음을 실행하세요.
python manage.py createsuperuser
사용자 계정의 또 다른 이점은 개인화된 데이터를 데이터베이스에 저장하는 것입니다. 기본적으로 Django는 사용자 이름과 비밀번호만 필요하지만 사용자가 이름, 성 및 이메일 주소를 입력할 수 있는 선택적 필드를 제공합니다. Django 웹사이트에서 완전한 모델 참조를 읽을 수 있습니다. 우리는 아래에서 이 모델을 확장하는 것에 대해 논의할 것입니다.
보안 및 안정성
Django에는 사용자 모델과 함께 실질적인 암호 관리 미들웨어가 포함되어 있습니다. 사용자 암호는 전체 숫자가 아닌 8자 이상이어야 하며 사용자 이름과 너무 일치하지 않아야 하며 가장 일반적인 20,000개의 암호 목록에 포함되지 않아야 합니다. Django 스톡 양식은 이러한 요구 사항을 확인합니다. 암호가 서버로 전송되면 기본적으로 SHA256 해시와 함께 PBKDF2 알고리즘을 사용하여 저장되기 전에 암호화됩니다. 전반적으로 기본 암호 시스템은 개발자의 노력 없이 강력한 보안을 제공합니다. 특정 전문 지식과 응용 프로그램에서 암호가 처리되는 방식을 변경해야 하는 설득력 있는 이유가 없는 한 이 동작을 수정하지 마십시오.
또 다른 편리한 내장 기능은 사용자 이름이 고유해야 한다는 요구 사항입니다. 생각해 보면 "djangofan1"이라는 사용자 이름을 가진 두 명의 사용자가 있고 서버가 해당 사용자 이름에 대한 로그인 요청을 수신했다면 어떤 사용자가 애플리케이션에 액세스하려고 했는지 알 수 없습니다. 불행히도 "djangofan1"으로 등록을 시도하는 두 번째 사용자는 "djangofan2"와 같은 다른 이름을 선택해야 합니다. 이 고유성 제약 조건은 데이터베이스 수준에서 적용되지만 Django가 제공하는 양식에 의해 다시 확인됩니다.
마지막으로 사용자 삭제에 대한 참고 사항입니다. 사용자를 삭제할 수도 있지만 대부분의 복잡한 응용 프로그램에는 각 사용자 계정에 연결된 많은 리소스가 있습니다. 연결된 객체를 제거하지 않고 사용자를 효과적으로 삭제하려면 대신 사용자의 is_active
필드를 false로 설정하십시오. 그런 다음 이러한 다른 리소스는 자체적으로 삭제되지 않고 계정과 연결된 상태로 유지되며 사용자 계정은 수퍼유저가 언제든지 다시 활성화할 수 있습니다. 이렇게 하면 사용자 이름이 해제되지 않지만 사용자 이름을 임의의 고유 값으로 변경하는 것과 함께 계정을 비활성으로 설정하면 동일한 효과를 얻을 수 있습니다. 마지막으로, 사이트 정책 또는 해당 지역 법률에서 사용자 계정을 완전히 삭제할 수 있도록 요구하는 경우 is_active
접근 방식으로는 충분하지 않습니다.
특정 전문 지식과 응용 프로그램에서 암호가 처리되는 방식을 변경해야 하는 설득력 있는 이유가 없는 한 이 동작을 수정하지 마십시오.
"
표준 사용
새 사용자 계정을 등록하려고 할 때 이를 위한 보기는 아마도 views.py 에서 다음과 같이 보일 것입니다.
from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.forms import UserCreationForm def signup(request): if request.user.is_authenticated: return redirect('/') if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): form.save() username = form.cleaned_data.get('username') password = form.cleaned_data.get('password1') user = authenticate(username=username, password=password) login(request, user) return redirect('/') else: return render(request, 'signup.html', {'form': form}) else: form = UserCreationForm() return render(request, 'signup.html', {'form': form})
다음과 같이 분해해 보겠습니다.
- 사용자가 이미 로그인되어 있는 경우 가입 페이지에서 다른 곳으로 리디렉션합니다.
- 요청 방법이 POST라면 사용자 생성을 위한 양식이 이미 작성되었으며 사용자를 생성할 때라는 의미입니다.
- 먼저 사용자가 제공한 데이터를 사용하여 백엔드에서 양식 개체를 구성합니다.
- 양식이 유효하면 사용자를 생성하고 로그인한 다음 메인 페이지로 보냅니다.
- 그렇지 않으면 잘못된 데이터에 대한 정보와 함께 사용자 생성 페이지에 다시 덤프하십시오(예: 이미 사용 중인 사용자 이름을 요청함).
- 그렇지 않으면 사용자가 처음으로 페이지에 액세스하는 것이며 새 계정을 만들기 위한 양식을 만나야 합니다.
이제 계정 로그인을 검토 중입니다.

from django.shortcuts import render, redirect from django.contrib.auth import authenticate, login from django.contrib.auth.forms import AuthenticationForm def signin(request): if request.user.is_authenticated: return render(request, 'homepage.html') if request.method == 'POST': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('/') else: form = AuthenticationForm(request.POST) return render(request, 'signin.html', {'form': form}) else: form = AuthenticationForm() return render(request, 'signin.html', {'form': form})
또 다른 고장:
- 사용자가 이미 로그인되어 있는 경우 로그인 페이지에서 사용자를 리디렉션합니다.
- 요청 방법이 POST인 경우 로그인 양식이 작성되었으며 계정에 대해 사용자를 인증할 시간입니다.
- 먼저 사용자가 제공한 데이터로 사용자를 인증합니다.
- 사용자 이름과 암호가 계정과 일치하는 경우 사용자를 로그인하십시오.
- 그렇지 않으면 양식 정보가 미리 채워진 상태로 로그인 페이지로 다시 가져옵니다.
- 그렇지 않으면 사용자가 페이지에 처음 액세스하는 것이며 로그인 양식을 충족해야 합니다.
마지막으로 사용자는 결국 로그아웃할 수 있습니다. 이 요청의 기본 코드는 간단합니다.
from django.shortcuts import render, redirect from django.contrib.auth import logout def signout(request): logout(request) return redirect('/')
사용자가 계정에 로그인하면 해당 장치에서 로그아웃할 때까지 "세션"이 있습니다. 이 시간 동안 브라우저의 후속 요청은 계정 전용 페이지에 액세스할 수 있습니다. 사용자는 동시에 여러 세션을 활성화할 수 있습니다. 기본적으로 세션은 시간 초과되지 않습니다.
사용자는 장치에 활성 세션이 있는 동안 request.user.is_authenticated
확인에 대해 True
로 등록합니다. 로그인한 사용자에게만 페이지를 제한하는 또 다른 방법은 함수 위의 @login_required
데코레이터입니다. 여기에서 자세히 설명하는 동일한 작업을 수행하는 다른 여러 방법이 있습니다.
이 수준의 구성이 수행하려는 것보다 많은 경우 사용자 관리에 대한 훨씬 더 기본적인 접근 방식이 있습니다. 이러한 주식 인증 보기는 사용자 관리를 위한 표준 경로, 보기 및 양식을 제공하며 사용자 정의 URL에 할당하거나 사용자 정의 템플릿을 전달하거나 더 많은 제어를 위해 보기를 하위 분류하여 수정할 수 있습니다.
사용자 모델 확장
일반적으로 세분화된 액세스 제어를 제공하거나 계정당 더 많은 사용자 데이터를 저장하려면 사용자 모델을 확장해야 합니다. 아래에서 몇 가지 일반적인 경우를 살펴보겠습니다.
사용자 모델에서 필드 삭제
이 섹션의 헤더와 달리 사용자 모델이나 관련 데이터베이스 스키마를 직접 변경하는 것은 권장하지 않습니다! 일반 사용자 모델은 새 Django 프로젝트를 설정하는 동안 기본적으로 데이터베이스에 설정됩니다. 기본 사용자 모델과 너무 많이 관련되어 있어 이를 변경하면 애플리케이션에 예기치 않은 영향이 발생할 수 있습니다(특히 타사 라이브러리를 사용하는 경우). 따라서 필드를 추가하거나 제거하는 것은 권장되지 않으며 프레임워크에서 쉽게 만들지 않습니다.
기본적으로 사용자에게 필요한 필드는 사용자 이름과 암호뿐입니다. 다른 필드를 사용하지 않으려면 이름, 성 또는 이메일 주소 없이 사용자를 만들 수 있으므로 해당 필드의 존재를 무시하십시오. 원하지 않는 경우 무시할 수도 있는 last_login 및 date_joined와 같은 기본 필드 모음이 있습니다. 사용자 모델에서 선택적 필드를 삭제해야 하는 실제 기술 제약이 있는 경우 이미 이에 대해 알고 있으므로 이 기사가 필요하지 않을 것입니다.
사용자 모델에서 필드를 삭제하려는 일반적인 이유는 이메일을 고유 식별자로 사용하기 위해 사용자 이름을 삭제하는 것입니다. 이 경우 양식 데이터에서 사용자를 생성하거나 요청을 인증할 때 이메일 필드에 사용하는 것 외에 사용자 이름으로 이메일 주소를 입력하기만 하면 됩니다. 사용자 이름 필드는 사용자 이름이 이메일 주소로 형식화된 경우에도 고유성 제약 조건을 적용합니다. 문자열은 문자열이므로 동일하게 취급됩니다.
기본 사용자 모델과 너무 많이 관련되어 있어 이를 변경하면 특히 타사 라이브러리를 사용하는 경우 애플리케이션에 예기치 않은 영향을 미칠 수 있습니다.
"
프로필로 필드 추가하기
마찬가지로 사용자에 대한 추가 정보를 저장하려는 경우 기본 사용자 모델을 수정하려고 시도해서는 안 됩니다. 단일 필드에 대해서도 기존 사용자와 일대일 관계로 자신의 개체를 정의합니다. 이 추가 모델은 종종 Profile
이라고 합니다. 각 사용자의 중간 이름과 생년월일(dob)을 저장하고 싶다고 가정해 보겠습니다. Profile
은 models.py 에서 다음과 같이 정의됩니다.
from django.db import models from django.contrib.auth.models import User class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) middle_name = models.CharField(max_length=30, blank=True) dob = models.DateField(null=True, blank=True)
사용자 지정 액세스 제어
귀하의 애플리케이션은 정보 및 기능에 액세스하기 위해 다양한 유형의 사용자를 구분해야 할 수 있습니다. Django는 사용자 정의 세분화된 액세스 제어(권한 및 그룹)를 생성하기 위한 시스템을 제공합니다.
권한은 리소스에 대한 액세스를 결정하는 개체입니다. 사용자는 하나 이상의 권한을 가질 수 있습니다. 예를 들어, 제품 테이블에 대한 읽기 액세스 권한과 고객 테이블에 대한 쓰기 액세스 권한이 있을 수 있습니다. 권한의 정확한 구현은 애플리케이션에 따라 크게 다르지만 Django의 접근 방식은 데이터에 대한 권한을 정의하고 이러한 권한을 사용자에게 할당하는 것을 직관적으로 만듭니다.
엔터프라이즈 및 기타 대규모 조직을 위한 애플리케이션은 종종 역할 기반 액세스 제어를 구현합니다. 기본적으로 사용자는 다양한 역할을 가질 수 있으며 각 역할에는 특정 권한이 있습니다. 이 패턴을 구현하기 위한 Django의 도구는 Group입니다. 그룹에는 여러 개의 권한이 있을 수 있으며 각 권한은 원하는 수의 그룹에 할당될 수 있습니다. 그런 다음 사용자는 직접 권한을 얻는 것이 아니라 그룹에 대한 구성원 자격을 통해 권한을 얻어 애플리케이션을 더 쉽게 관리할 수 있습니다.
개요: 지불 공급자 통합
지불 프로세서를 통합하는 정확한 프로세스는 애플리케이션과 제공업체에 따라 크게 다릅니다. 그러나 일반적인 용어로 프로세스를 다룰 것입니다.
지불 아웃소싱의 주요 이점 중 하나는 공급자가 신용 카드 정보와 같이 엄격하게 규제되는 데이터를 저장하고 검증할 책임이 있다는 것입니다. 그런 다음 서비스는 지불 내역에 대한 데이터와 함께 일부 고유한 사용자 토큰을 애플리케이션과 공유합니다. 프로필을 추가하는 것처럼 핵심 User
와 연결된 모델을 만들고 해당 모델에 데이터를 저장할 수 있습니다. 암호와 마찬가지로 중요한 정보를 부적절하게 저장하지 않도록 공급자와의 통합을 따르는 것이 중요합니다.
개요: 소셜 로그인
제가 간단히 언급하고 싶은 또 다른 광범위하고 복잡한 분야는 소셜 로그인입니다. Facebook 및 Google과 같은 대규모 플랫폼과 GitHub와 같은 소규모 사이트는 서비스를 사용하여 사용자를 인증하기 위한 API를 제공합니다. 지불 공급자와 유사하게 이것은 계정을 데이터베이스의 계정에 연결하는 레코드를 데이터베이스에 생성합니다.
사용자가 새로운 로그인 자격 증명 세트를 만들지 않고도 쉽게 가입할 수 있도록 사이트에 소셜 인증을 포함할 수 있습니다. 애플리케이션이 소셜 인증 옵션을 제공하는 특정 사이트를 이미 사용하고 있는 고객만을 대상으로 하는 경우 진입 장벽을 낮추어 해당 시장에서 사용자를 유치하는 데 도움이 될 수 있습니다. 또한 애플리케이션이 타사 서비스에서 사용자 데이터에 액세스하려는 경우 인증 중에 계정을 연결하면 권한 부여 프로세스가 간소화됩니다.
그러나 소셜 인증을 사용하는 데에는 단점이 있습니다. 타사 공급자의 API 변경 또는 중단으로 인해 애플리케이션의 가동 시간 또는 개발 활동이 중단될 수 있습니다. 일반적으로 외부 종속성은 애플리케이션에 복잡성을 추가합니다. 마지막으로, 통합하려는 제3자의 데이터 수집 및 사용 정책을 고려하고 해당 정책이 귀하와 귀하의 사용자 기대에 부합하는지 확인하는 것이 좋습니다.
소셜 인증이 애플리케이션에 적합하다고 결정했다면 다행히도 이를 위한 라이브러리가 있습니다. Python Social Auth for Django는 Django 프로젝트에서 Python의 소셜 인증 생태계 기능을 활성화하기 위한 패키지입니다.
마무리
사용자 계정이 보편적인 만큼 널리 사용되면 동일한 문제를 불필요하게 해결할 수 있습니다. 이 기사가 Django에서 사용할 수 있는 강력한 기능의 범위를 보여주고 사용자 계정을 생성할 때 애플리케이션의 기본 책임에 대한 이해를 제공했으면 합니다.
Django Highlights는 Django에서 웹 개발의 중요한 개념을 소개하는 시리즈입니다. 각 기사는 프론트엔드 개발자와 디자이너가 코드베이스의 "나머지 절반"에 대해 더 깊이 이해할 수 있도록 돕기 위해 Django 개발 측면에 대한 독립 실행형 가이드로 작성되었습니다. 이 기사는 대부분 이론과 관례에 대한 이해를 돕기 위해 작성되었지만 Django 3.0으로 작성된 일부 코드 샘플이 포함되어 있습니다. 템플릿, 관리자 사용자, 모델 및 양식을 포함하여 이 기사에서 다룬 몇 가지 개념은 이 시리즈의 향후 기사에서 개별적으로 자세히 살펴볼 것입니다.
시리즈의 추가 부품 :
- Django 하이라이트: 템플릿을 사용하면 줄바꿈(2부)
- Django 하이라이트: 모델, 관리자 및 관계형 데이터베이스 활용(3부)
- Django 하이라이트: 정적 자산 및 미디어 파일 랭글링(4부)