This document explains the usage of Django’s authentication system in its default configuration. This configuration has evolved to serve the most common project needs, handling a reasonably wide range of tasks, and has a careful implementation of passwords and permissions. For projects where authentication needs differ from the default, Django supports extensive extension and customization of authentication.
Django authentication provides both authentication and authorization together and is generally referred to as the authentication system, as these features are somewhat coupled.
사용자
객체¶User
objects are the core of the
authentication system. They typically represent the people interacting with
your site and are used to enable things like restricting access, registering
user profiles, associating content with creators etc. Only one class of user
exists in Django’s authentication framework, i.e., 'superusers'
or admin 'staff'
users are just user objects with
special attributes set, not different classes of user objects.
디폴트 사용자의 주요 속성은 :
See the full API documentation
for
full reference, the documentation that follows is more task oriented.
The most direct way to create users is to use the included
create_user()
helper function:
>>> from django.contrib.auth.models import User
>>> user = User.objects.create_user("john", "lennon@thebeatles.com", "johnpassword")
# At this point, user is a User object that has already been saved
# to the database. You can continue to change its attributes
# if you want to change other fields.
>>> user.last_name = "Lennon"
>>> user.save()
만약 Django admin 이 설치되어 있다면, :ref:` 사용자를 상호작용적으로 추가<auth-admin>` 할 수 있다.
Create superusers using the createsuperuser
command:
$ python manage.py createsuperuser --username=joe --email=joe@example.com
...\> py manage.py createsuperuser --username=joe --email=joe@example.com
당신은 프롬프트를 통해 패스워드 입력을 해야할 것 입니다. 패스워드를 입력한 뒤, 사용자가 바로 생성될 것입니다. 만약 --username
or --email
옵션들을 사용하지 않으면, 이들의 값을 위해 프롬프트로 물어볼 것입니다.
Django 는 사용자 모델에 원본 패스워드(일반 텍스트)를 저장하지 않고, 오직 해쉬만 저장합니다. (디테일하게 보기 비밀번호 조작하기 문서 ). 이로 인해, 사용자의 패스워드 속성을 직접적으로 조작하려 시도하지 마십시오. 이는 사용자 생성을 위해 헬퍼 함수를 사용하는 이유입니다.
사용자의 패스워드를 변경하기 위해, 여러 옵션이 있습니다.
manage.py changepassword *username*
offers a method
of changing a user’s password from the command line. It prompts you to
change the password of a given user which you must enter twice. If
they both match, the new password will be changed immediately. If you
do not supply a user, the command will attempt to change the password
whose username matches the current system user.
You can also change a password programmatically, using
set_password()
:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(username="john")
>>> u.set_password("new password")
>>> u.save()
If you have the Django admin installed, you can also change user’s passwords on the authentication system’s admin pages.
Django also provides views and forms that may be used to allow users to change their own passwords.
Changing a user’s password will log out all their sessions. See 패스워드 변경시 세션 무효화 for details.
authenticate
(request=None, **credentials)¶Use authenticate()
to verify a set of
credentials. It takes credentials as keyword arguments, username
and
password
for the default case, checks them against each
authentication backend, and returns a
User
object if the credentials are
valid for a backend. If the credentials aren’t valid for any backend or if
a backend raises PermissionDenied
, it
returns None
. For example:
from django.contrib.auth import authenticate
user = authenticate(username="john", password="secret")
if user is not None:
# A backend authenticated the credentials
...
else:
# No backend authenticated the credentials
...
request
is an optional HttpRequest
which is
passed on the authenticate()
method of the authentication backends.
참고
This is a low level way to authenticate a set of credentials; for
example, it’s used by the
RemoteUserMiddleware
. Unless
you are writing your own authentication system, you probably won’t use
this. Rather if you’re looking for a way to login a user, use the
LoginView
.
Django에는 권한 시스템이 내장되어 있다. 해당 권한 시스템은 특정 사용자 및 사용자 그룹에 권한을 할당하는 방법을 제공한다.
그것은 Django 관리자 사이트에 사용 되지만 당신만의 소스코드에 사용할 수도 있다.
Django 관리자 사이트는 권한을 다음과 같이 사용한다:
권한은 객체 유형별로 설정할 수 있을 뿐만 아니라 특정 객체 인스턴스별로도 설정할 수 있다.
ModelAdmin
클래스별 has_view_permission()
, has_add_permission()
, has_change_permission()
, has_delete_permission()
method를 사용하여 동일한 유형의 다른 객체 인스턴스에 대한 권한을 커스터마이즈 할 수 있다.
User
객체에는 ``groups``와 ``user_permissions``라는 두 개의 다대다 필드가 있다. User
객체는 다른 Django model::와 동일한 방식으로 관련된 객체에 액세스할 수 있다.
myuser.groups.set([group_list])
myuser.groups.add(group, group, ...)
myuser.groups.remove(group, group, ...)
myuser.groups.clear()
myuser.user_permissions.set([permission_list])
myuser.user_permissions.add(permission, permission, ...)
myuser.user_permissions.remove(permission, permission, ...)
myuser.user_permissions.clear()
``django.contrib.auth``가 INSTALLED_APPS
설정에 나열되면 설치된 애플리케이션 중 하나에 정의된 각 Django 모델에 대해 네 가지 기본 권한인 추가, 변경, 삭제 및 보기가 생성되도록 한다.
이 권한은 다음을 실행할 때 생성된다. manage.py migrate
; INSTALLED_APPS`에 ``django.contrib.auth``를 추가한 후 ``migrate``를 처음 실행할 때, 기본 권한은 이전에 설치된 모든 모델과 해당 시점에 설치되는 모든 새 모델에 대해 생성된다. 이후 :djadmin:`manage.py migrate <migrate>`를 실행할 때마다 새 모델에 대한 기본 권한을 생성한다. (권한을 생성하는 함수는 :data:`~django.db.models.signals.post_migrate
신호에 연결됨). .
app_label
foo
와 ``Bar``라는 모델이 있는 애플리케이션이 있다고 가정하고 기본 권한을 테스트하려면 다음을 사용해야 한다:
user.has_perm('foo.add_bar')
user.has_perm('foo.change_bar')
user.has_perm('foo.delete_bar')
user.has_perm('foo.view_bar')
Permission
모델은 직접 액세스하는 경우가 거의 없다.
django.contrib.auth.models.Group
모델은 사용자를 분류하는 일반적인 방법이므로 해당 사용자에게 권한이나 다른 레이블을 적용할 수 있다. 사용자는 여러 그룹에 속할 수 있다.
그룹의 사용자는 자동으로 해당 그룹에 부여된 권한을 갖는다. 예를 들어 Site editors
그룹에 can_edit_home_page
권한이 있는 경우 해당 그룹의 모든 사용자는 해당 권한을 갖게 됩니다.
권한 외에도 그룹은 사용자를 분류하여 레이블이나 확장된 기능을 제공하는 편리한 방법이다. 예를 들어 'Special users'
그룹을 만들고 사이트의 회원 전용 부분에 대한 액세스 권한을 부여하거나 회원 전용 이메일 메시지를 보내는 코드를 작성할 수 있다.
custom permissions <custom-permissions>`은 모델의 ``Meta` 클래스 내에서 정의할 수 있지만 권한을 직접 생성할 수도 있다. 예를 들어 myapp
::에서 BlogPost
모델에 대한 can_publish
권한을 생성할 수 있다.
from myapp.models import BlogPost
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.create(
codename="can_publish",
name="Can Publish Posts",
content_type=content_type,
)
그런 다음 user_permissions
속성을 통해 권한을 User`에 할당하거나 또는 ``permissions`
속성을 통해 :class:`~django.contrib.auth.models.Group`에 할당할 수 있다.
:class:`~django.contrib.auth.backends.ModelBackend`는 권한 확인을 위해 가져와야 하는 처음 사용자 객체에 대한 권한을 캐시한다. 권한은 일반적으로 추가된 직후 확인되지 않기 때문에 일반적으로 요청-응답 주기에 적합하다(예: 관리자에서). 예를 들어 테스트나 보기에서 권한을 추가하고 즉시 확인하는 경우 가장 쉬운 솔루션은 데이터베이스에서 사용자를 다시 가져오는 것이다. 예를 들어:
from django.contrib.auth.models import Permission, User
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404
from myapp.models import BlogPost
def user_gains_perms(request, user_id):
user = get_object_or_404(User, pk=user_id)
# any permission check will cache the current set of permissions
user.has_perm("myapp.change_blogpost")
content_type = ContentType.objects.get_for_model(BlogPost)
permission = Permission.objects.get(
codename="change_blogpost",
content_type=content_type,
)
user.user_permissions.add(permission)
# Checking the cached permission set
user.has_perm("myapp.change_blogpost") # False
# Request new instance of User
# Be aware that user.refresh_from_db() won't clear the cache.
user = get_object_or_404(User, pk=user_id)
# Permission cache is repopulated from the database
user.has_perm("myapp.change_blogpost") # True
...
프록시 모델은 실제 모델과 정확히 같은 방식으로 작동한다. 권한은 프록시 모델의 자체 콘텐츠 유형을 사용하여 생성된다. 프록시 모델은 하위 클래스로 분류되는 실제 모델의 권한을 상속하지 않는다.
class Person(models.Model):
class Meta:
permissions = [("can_eat_pizzas", "Can eat pizzas")]
class Student(Person):
class Meta:
proxy = True
permissions = [("can_deliver_pizzas", "Can deliver pizzas")]
>>> # Fetch the content type for the proxy model.
>>> content_type = ContentType.objects.get_for_model(Student, for_concrete_model=False)
>>> student_permissions = Permission.objects.filter(content_type=content_type)
>>> [p.codename for p in student_permissions]
['add_student', 'change_student', 'delete_student', 'view_student',
'can_deliver_pizzas']
>>> for permission in student_permissions:
... user.user_permissions.add(permission)
...
>>> user.has_perm("app.add_person")
False
>>> user.has_perm("app.can_eat_pizzas")
False
>>> user.has_perms(("app.add_student", "app.can_deliver_pizzas"))
True
Django는 :doc:`sessions`와 미들웨어를 사용하여 인증 시스템을 :class:`request objects <django.http.HttpRequest>`에 연결한다.
이들은 현재 사용자를 나타내는 모든 요청에 대해 request.user
속성을 제공한다. 현재 사용자가 로그인하지 않은 경우 이 속성은 :class:`~django.contrib.auth.models.AnonymousUser`의 인스턴스로 설정되고, 그렇지 않으면 :class:`~django.contrib.auth.models.User`의 인스턴스가 된다.
그것들을 다음과 같이 :attr:`~django.contrib.auth.models.User.is_authenticated`로 구분할 수 있다.
if request.user.is_authenticated:
# Do something for authenticated users.
...
else:
# Do something for anonymous users.
...
현재 세션에 연결하려는 인증된 사용자가 있는 경우 - 이것은 login()
기능으로 수행된다.
login
(request, user, backend=None)¶사용자를 로그인하려면 보기에서 HttpRequest()
객체와 User
객체가 필요하다. :func:`~django.contrib.auth.login()`은 Django의 세션 프레임워크를 사용하여 세션에 사용자 ID를 저장한다.
익명 세션 동안 설정된 모든 데이터는 사용자가 로그인한 후에도 세션에 유지된다.
이 예는 authenticate()
및 login()
:을 모두 사용하는 방법을 보여준다.
from django.contrib.auth import authenticate, login
def my_view(request):
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to a success page.
...
else:
# Return an 'invalid login' error message.
...
사용자가 로그인하면 사용자의 세션에 사용자의 ID와 인증에 사용된 백엔드가 저장된다. 이렇게 하면 동일한 :ref:`authentication backend <authentication-backends>`가 향후 요청에서 사용자의 세부 정보를 가져올 수 있다. 세션에 저장할 인증 백엔드는 다음과 같이 선택된다.
backend
인수 값을 사용한다.user.backend
속성 값을 사용한다. 이렇게 하면 authenticate()
, login()
: , backend`()
속성을 설정한다사례 1과 2의 경우 backend
인수 또는 user.backend
속성의 값은 실제 백엔드 클래스가 아니라 점으로 구분된 import 경로 문자열(예: :setting:`AUTHENTICATION_BACKENDS`에 있음)이어야 한다.
logout
(request)¶django.contrib.auth.login()`을 통해 로그인한 사용자를 로그아웃하려면 보기 내에서 :func:`django.contrib.auth.logout()`을 사용한다. :class:`~django.http.HttpRequest()
객체를 사용하며 반환 값이 없다. 예시:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
:func:`~django.contrib.auth.logout()`은 사용자가 로그인하지 않은 경우 오류를 발생시키지 않는다.
:func:`~django.contrib.auth.logout()`을 호출하면 현재 요청에 대한 세션 데이터가 완전히 지워진다. 모든 기존 데이터가 제거된다. 이는 다른 사람이 동일한 웹 브라우저를 사용하여 로그인하고 이전 사용자의 세션 데이터에 액세스하는 것을 방지하기 위한 것이다. 사용자가 로그아웃한 직후에 사용할 수 있는 세션에 무엇이든 넣고 싶다면 :func:`django.contrib.auth.logout()`을 호출한 후에 수행하십시오.
페이지에 대한 액세스를 제한하는 기본적인 방법은 :attr:`request.user.is_authenticated <django.contrib.auth.models.User.is_authenticated>`를 확인하고 로그인 페이지로 리디렉션하는 것이다.
from django.conf import settings
from django.shortcuts import redirect
def my_view(request):
if not request.user.is_authenticated:
return redirect(f"{settings.LOGIN_URL}?next={request.path}")
# ...
…또는 오류 메시지 표시한다.
from django.shortcuts import render
def my_view(request):
if not request.user.is_authenticated:
return render(request, "myapp/login_error.html")
# ...
login_required
데코레이터¶login_required
(redirect_field_name='next', login_url=None)¶바로 가기로 편리한 login_required()
decorator::를 사용할 수 있다.
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
:func:`~django.contrib.auth.decorators.login_required`는 다음을 수행한다.
settings.LOGIN_URL<LOGIN_URL> `로 리디렉션한다. 예: `
/accounts/login/?next=/polls/3/``.기본적으로 인증 성공 시 사용자가 리디렉션되어야 하는 경로는 "next"``라는 쿼리 문자열 매개변수에 저장된다. 이 매개변수에 다른 이름을 사용하고 싶다면 :func:`~django.contrib.auth.decorators.login_required`는 선택적 ``redirect_field_name
매개변수::를 사용한다.
from django.contrib.auth.decorators import login_required
@login_required(redirect_field_name="my_redirect_field")
def my_view(request):
...
redirect_field_name``에 값을 제공하면 리디렉션 경로를 저장하는 템플릿 컨텍스트 변수가 ``"next"
(기본값) 이 아닌 redirect_field_name
값을 키로 사용하기 때문에 로그인 템플릿도 커스터마이즈해야 할 가능성이 크다.
login_required`는 선택적 ``login_url`()
매개변수도 사용한다. 예시:
from django.contrib.auth.decorators import login_required
@login_required(login_url="/accounts/login/")
def my_view(request):
...
login_url
매개변수를 지정하지 않으면 :setting:`settings.LOGIN_URL <LOGIN_URL>`과 로그인 보기가 제대로 연결되어 있는지 확인해야 합니다. 예를 들어 기본값을 사용하여 URLconf에 다음 줄을 추가한다.
from django.contrib.auth import views as auth_views
path("accounts/login/", auth_views.LoginView.as_view()),
:setting:`settings.LOGIN_URL <LOGIN_URL>`은 뷰 함수 이름과 :ref:`named URL patterns <naming-url-patterns>`도 허용한다. 이렇게 하면 설정을 업데이트하지 않고도 URLconf 내에서 로그인 뷰를 자유롭게 다시 매핑할 수 있다.
참고
login_required
decorator는 사용자의 is_active
플래그를 확인하지 않지만 기본 :setting:`AUTHENTICATION_BACKENDS`는 비활성 사용자를 거부한다.
더 보기
Django의 관리자를 위한 커스텀 뷰를 작성하는 경우(또는 내장된 뷰에서 사용하는 것과 동일한 권한 부여 확인이 필요한 경우) django.contrib.admin.views.decorators.staff_member_required()
decorator가 ``login_required()``의 유용한 대안임을 찾을 수 있다.
LoginRequiredMixin
mixin¶:doc:class-based views </topics/class-based-views/index>`를 사용할 때 ``LoginRequiredMixin``을 사용하여 ``login_required``와 동일한 동작을 얻을 수 있다. 이 믹스인은 상속 목록에서 가장 왼쪽에 있어야 한다.
LoginRequiredMixin
¶뷰가 이 믹스인을 사용하는 경우 인증되지 않은 사용자의 모든 요청은 로그인 페이지로 리디렉션되거나 raise_exception
매개변수에 따라 HTTP 403 Forbidden 오류가 표시된다.
:class:`~django.contrib.auth.mixins.AccessMixin`의 매개변수를 설정하여 권한이 없는 사용자 처리를 커스터마이즈할 수 있다.
from django.contrib.auth.mixins import LoginRequiredMixin
class MyView(LoginRequiredMixin, View):
login_url = "/login/"
redirect_field_name = "redirect_to"
참고
login_required
데코레이터와 마찬가지로 이 믹스인은 사용자의 is_active
플래그를 확인하지 않지만 기본 :setting:`AUTHENTICATION_BACKENDS`는 비활성 사용자를 거부한다.
특정 권한이나 다른 테스트를 기반으로 액세스를 제한하려면 기본적으로 이전 섹션에서 설명한 것과 동일한 작업을 수행한다.
뷰에서 직접 :attr:`request.user <django.http.HttpRequest.user>`에 대한 테스트를 실행할 수 있다. 예를 들어, 이 뷰는 사용자가 원하는 도메인에 이메일이 있는지 확인하고 그렇지 않은 경우 로그인 페이지로 리디렉션한다.
from django.shortcuts import redirect
def my_view(request):
if not request.user.email.endswith("@example.com"):
return redirect("/login/?next=%s" % request.path)
# ...
user_passes_test
(test_func, login_url=None, redirect_field_name='next')¶단축키로 콜러블이 False``를 반환할 때 리디렉션을 수행하는 편리한 ``user_passes_test
decorator를 사용할 수 있다.
from django.contrib.auth.decorators import user_passes_test
def email_check(user):
return user.email.endswith("@example.com")
@user_passes_test(email_check)
def my_view(request):
...
User()
객체를 취하고 사용자가 페이지를 볼 수 있는 경우 ``True``를 반환하는 콜러블. :func:`~django.contrib.auth.decorators.user_passes_test`는 자동으로 :class:`~django.contrib.auth.models.User`가 익명이 아닌지 확인하지 않는다는 점에 유의해야 한다.
:func:`~django.contrib.auth.decorators.user_passes_test`는 두 개의 선택적 인수를 사용한다.
login_url
redirect_field_name
예시:
@user_passes_test(email_check, login_url="/login/")
def my_view(request):
...
UserPassesTestMixin
¶:doc:`class-based views </topics/class-based-views/index>`를 사용하는 경우 ``UserPassesTestMixin``을 사용하여 이를 수행할 수 있다.
test_func
()¶수행되는 테스트를 제공하려면 클래스의 test_func()
메서드를 재정의해야 한다. 또한 :class:`~django.contrib.auth.mixins.AccessMixin`의 매개변수를 설정하여 권한이 없는 사용자 처리를 커스터마이즈할 수 있다.
from django.contrib.auth.mixins import UserPassesTestMixin
class MyView(UserPassesTestMixin, View):
def test_func(self):
return self.request.user.email.endswith("@example.com")
get_test_func
()¶또한 get_test_func()
메소드를 재정의하여 mixin이 검사를 위해 (test_func()
대신) 다른 이름의 함수를 사용하도록 할 수도 있다.
UserPassesTestMixin
스태킹(Stacking)
``UserPassesTestMixin``이 구현되는 방식으로 인해 상속 목록에 쌓을 수 없다. 다음은 작동하지 않는다:
class TestMixin1(UserPassesTestMixin):
def test_func(self):
return self.request.user.email.endswith("@example.com")
class TestMixin2(UserPassesTestMixin):
def test_func(self):
return self.request.user.username.startswith("django")
class MyView(TestMixin1, TestMixin2, View):
...
``TestMixin1``이 ``super()``를 호출하고 해당 결과를 고려하면 ``TestMixin1``은 더 이상 독립 실행형으로 작동하지 않는다.
permission_required
decorator¶permission_required
(perm, login_url=None, raise_exception=False)¶사용자에게 특정 권한이 있는지 여부를 확인하는 것은 상대적으로 일반적인 작업이다. 그런 이유로 Django는 이 경우에 대한 바로 가기를 제공한다. permission_required()
decorator:
from django.contrib.auth.decorators import permission_required
@permission_required("polls.add_choice")
def my_view(request):
...
has_perm()
메서드와 마찬가지로 권한 이름은 "<app label>.<permission codename>"
형식을 취한다(즉, polls
애플리케이션의 모델에 대한 권한의 경우 polls.add_choice
).
decorator는 반복 가능한 권한을 가질 수도 있습니다. 이 경우 사용자는 뷰에 액세스하기 위해 모든 권한을 가지고 있어야 한다.
permission_required()`도 선택적 ``login_url`()
매개변수를 사용한다.
from django.contrib.auth.decorators import permission_required
@permission_required("polls.add_choice", login_url="/loginpage/")
def my_view(request):
...
login_required()
데코레이터에서와 같이 ``login_url``의 기본값은 :setting:`settings.LOGIN_URL <LOGIN_URL>`이다.
raise_exception
매개변수가 지정되면 데코레이터는 로그인 페이지로 리디렉션하는 대신 :exc:`~django.core.exceptions.PermissionDenied`를 발생시켜 :ref:`403(HTTP Forbidden) view<http_forbidden_view>’를 표시한다.
``raise_exception``을 사용하고 사용자에게 먼저 로그인할 기회를 주고 싶다면 login_required()
데코레이터를 추가할 수 있다:
from django.contrib.auth.decorators import login_required, permission_required
@login_required
@permission_required("polls.add_choice", raise_exception=True)
def my_view(request):
...
이는 또한 :class:`.LoginView`의 ``redirect_authenticated_user=True``이고 로그인한 사용자에게 필요한 모든 권한이 없는 경우 리디렉션 루프를 방지한다.
PermissionRequiredMixin
믹스인¶:doc:`class-based views`에 권한 검사를 적용하려면 ``PermissionRequiredMixin``을 사용할 수 있다.
PermissionRequiredMixin
¶이 믹스인은 permission_required
decorator와 마찬가지로 뷰에 액세스하는 사용자에게 주어진 권한이 모두 있는지 여부를 확인하다. permission_required
매개변수를 사용하여 권한(또는 권한의 이터러블)을 지정해야 한다.
from django.contrib.auth.mixins import PermissionRequiredMixin
class MyView(PermissionRequiredMixin, View):
permission_required = "polls.add_choice"
# Or multiple of permissions:
permission_required = ["polls.view_choice", "polls.change_choice"]
:class:`~django.contrib.auth.mixins.AccessMixin`의 매개변수 중 하나를 설정하여 권한이 없는 사용자의 처리를 커스터마이즈할 수 있다.
다음 메서드를 재정의할 수도 있다.
get_permission_required
()¶믹스인에서 사용하는 권한 이름의 이터러블을 반환한다. 기본값은 permission_required
속성으로, 필요한 경우 튜플로 변환된다.
:doc:`class-based views </ref/class-based-views/index>`에서 액세스 제한을 쉽게 처리하기 위해 ``AccessMixin``을 사용하여 액세스가 거부될 때 보기의 동작을 구성할 수 있다. 인증된 사용자는 HTTP 403 Forbidden 응답으로 액세스가 거부된다. 익명 사용자는 :attr:`~django.contrib.auth.mixins.AccessMixin.raise_exception 속성에 따라 로그인 페이지로 리디렉션되거나 HTTP 403 Forbidden 응답이 표시된다.
AccessMixin
¶login_url
¶:meth:`get_login_url`에 대한 기본 반환 값이다. 기본값은 ``None``이며 이 경우 :meth:`get_login_url`은 :setting:`settings.LOGIN_URL <LOGIN_URL>`로 대체된다.
raise_exception
¶이 속성이 ``True``로 설정되면 조건이 충족되지 않을 때 PermissionDenied
예외가 발생한다. ``False``(기본값)인 경우 익명 사용자는 로그인 페이지로 리디렉션된다.
get_login_url
()¶테스트를 통과하지 못한 사용자가 리디렉션될 URL을 반환한다. 설정되면 :attr:`login_url`을 반환하고 그렇지 않으면 :setting:`settings.LOGIN_URL <LOGIN_URL>`을 반환한다.
get_permission_denied_message
()¶raise_exception`이 ``True``인 경우 이 메서드를 사용하여 사용자에게 표시하기 위해 오류 처리기에 전달되는 오류 메시지를 제어할 수 있다. 기본적으로 :attr:`permission_denied_message
속성을 반환한다.
get_redirect_field_name
()¶로그인 성공 후 사용자가 리디렉션되어야 하는 URL을 포함할 쿼리 매개변수의 이름을 반환한다. 이것을 ``None``으로 설정하면 쿼리 매개변수가 추가되지 않는다. 기본적으로 redirect_field_name
속성을 반환한다.
handle_no_permission
()¶raise_exception
값에 따라, 이 메소드는 PermissionDenied
예외를 발생시키거나 사용자를 ``login_url``로 리디렉션하며, 설정되어 있는 경우 선택적으로 ``redirect_field_name``을 포함한다.
AUTH_USER_MODEL`이 :class:`~django.contrib.auth.models.AbstractBaseUser`에서 상속하거나 자체 :meth:`~django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash()
메서드를 구현하는 경우, 인증된 세션에는 이 함수에서 반환된 해시가 포함된다. :class:`~django.contrib.auth.models.AbstractBaseUser`의 경우 비밀번호 필드의 HMAC이다. Django는 각 요청에 대한 세션의 해시가 요청 중에 계산된 해시와 일치하는지 확인한다. 이를 통해 사용자는 암호를 변경하여 모든 세션에서 로그아웃할 수 있다.
Django, PasswordChangeView
에 포함된 기본 비밀번호 변경 보기 및 django.contrib.auth
관리자의 user_change_password
보기는 새 비밀번호 해시로 세션을 업데이트하여 자신의 비밀번호를 변경한 사용자는 로그아웃되지 않는다. 사용자 정의 비밀번호 변경 보기가 있고 유사한 동작을 원하면 update_session_auth_hash()
기능을 사용하시오.
update_session_auth_hash
(request, user)¶이 함수는 현재 요청과 새 세션 해시가 파생될 업데이트된 사용자 객체를 가져오고 세션 해시를 적절하게 업데이트한다. 또한 도난당한 세션 쿠키가 무효화되도록 세션 키를 교체한다.
예시 용례:
from django.contrib.auth import update_session_auth_hash
def password_change(request):
if request.method == "POST":
form = PasswordChangeForm(user=request.user, data=request.POST)
if form.is_valid():
form.save()
update_session_auth_hash(request, form.user)
else:
...
참고
Since
get_session_auth_hash()
is based on SECRET_KEY
, secret key values must be
rotated to avoid invalidating existing sessions when updating your site to
use a new secret. See SECRET_KEY_FALLBACKS
for details.
Django provides several views that you can use for handling login, logout, and password management. These make use of the stock auth forms but you can pass in your own forms as well.
Django provides no default template for the authentication views. You should create your own templates for the views you want to use. The template context is documented in each view, see All authentication views.
There are different methods to implement these views in your project. The
easiest way is to include the provided URLconf in django.contrib.auth.urls
in your own URLconf, for example:
urlpatterns = [
path("accounts/", include("django.contrib.auth.urls")),
]
This will include the following URL patterns:
accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']
The views provide a URL name for easier reference. See the URL documentation for details on using named URL patterns.
If you want more control over your URLs, you can reference a specific view in your URLconf:
from django.contrib.auth import views as auth_views
urlpatterns = [
path("change-password/", auth_views.PasswordChangeView.as_view()),
]
The views have optional arguments you can use to alter the behavior of the
view. For example, if you want to change the template name a view uses, you can
provide the template_name
argument. A way to do this is to provide keyword
arguments in the URLconf, these will be passed on to the view. For example:
urlpatterns = [
path(
"change-password/",
auth_views.PasswordChangeView.as_view(template_name="change-password.html"),
),
]
All views are class-based, which allows you to easily customize them by subclassing.
This is a list with all the views django.contrib.auth
provides. For
implementation details see Using the views.
LoginView
¶URL name: login
See the URL documentation for details on using named URL patterns.
Methods and Attributes
template_name
¶The name of a template to display for the view used to log the user in.
Defaults to registration/login.html
.
next_page
¶The URL to redirect to after login. Defaults to
LOGIN_REDIRECT_URL
.
redirect_field_name
¶The name of a GET
field containing the URL to redirect to after
login. Defaults to next
. Overrides the
get_default_redirect_url()
URL if the given GET
parameter is
passed.
authentication_form
¶A callable (typically a form class) to use for authentication. Defaults
to AuthenticationForm
.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
redirect_authenticated_user
¶A boolean that controls whether or not authenticated users accessing
the login page will be redirected as if they had just successfully
logged in. Defaults to False
.
경고
If you enable redirect_authenticated_user
, other websites will
be able to determine if their visitors are authenticated on your
site by requesting redirect URLs to image files on your website. To
avoid this “social media fingerprinting” information
leakage, host all images and your favicon on a separate domain.
Enabling redirect_authenticated_user
can also result in a
redirect loop when using the permission_required()
decorator
unless the raise_exception
parameter is used.
success_url_allowed_hosts
¶A set
of hosts, in addition to request.get_host()
, that are safe for redirecting
after login. Defaults to an empty set
.
get_default_redirect_url
()¶Returns the URL to redirect to after login. The default implementation
resolves and returns next_page
if set, or
LOGIN_REDIRECT_URL
otherwise.
Here’s what LoginView
does:
GET
, it displays a login form that POSTs to the
same URL. More on this in a bit.POST
with user submitted credentials, it tries to log
the user in. If login is successful, the view redirects to the URL
specified in next
. If next
isn’t provided, it redirects to
settings.LOGIN_REDIRECT_URL
(which
defaults to /accounts/profile/
). If login isn’t successful, it
redisplays the login form.It’s your responsibility to provide the html for the login template
, called registration/login.html
by default. This template gets passed
four template context variables:
form
: A Form
object representing the
AuthenticationForm
.next
: The URL to redirect to after successful login. This may
contain a query string, too.site
: The current Site
,
according to the SITE_ID
setting. If you don’t have the
site framework installed, this will be set to an instance of
RequestSite
, which derives the
site name and domain from the current
HttpRequest
.site_name
: An alias for site.name
. If you don’t have the site
framework installed, this will be set to the value of
request.META['SERVER_NAME']
.
For more on sites, see “sites” 프레임워크.If you’d prefer not to call the template registration/login.html
,
you can pass the template_name
parameter via the extra arguments to
the as_view
method in your URLconf. For example, this URLconf line would
use myapp/login.html
instead:
path("accounts/login/", auth_views.LoginView.as_view(template_name="myapp/login.html")),
You can also specify the name of the GET
field which contains the URL
to redirect to after login using redirect_field_name
. By default, the
field is called next
.
Here’s a sample registration/login.html
template you can use as a
starting point. It assumes you have a base.html
template that
defines a content
block:
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.password.label_tag }}</td>
<td>{{ form.password }}</td>
</tr>
</table>
<input type="submit" value="login">
<input type="hidden" name="next" value="{{ next }}">
</form>
{# Assumes you set up the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
{% endblock %}
If you have customized authentication (see Customizing Authentication) you can use a custom authentication form by
setting the authentication_form
attribute. This form must accept a
request
keyword argument in its __init__()
method and provide a
get_user()
method which returns the authenticated user object (this
method is only ever called after successful form validation).
LogoutView
¶Logs a user out on POST
requests.
버전 4.1부터 폐지됨: Support for logging out on GET
requests is deprecated and will be
removed in Django 5.0.
URL name: logout
Attributes:
next_page
¶The URL to redirect to after logout. Defaults to
LOGOUT_REDIRECT_URL
.
template_name
¶The full name of a template to display after logging the user out.
Defaults to registration/logged_out.html
.
redirect_field_name
¶The name of a GET
field containing the URL to redirect to after log
out. Defaults to 'next'
. Overrides the
next_page
URL if the given GET
parameter is
passed.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
success_url_allowed_hosts
¶A set
of hosts, in addition to request.get_host()
, that are safe for redirecting
after logout. Defaults to an empty set
.
Template context:
title
: The string “Logged out”, localized.site
: The current Site
,
according to the SITE_ID
setting. If you don’t have the
site framework installed, this will be set to an instance of
RequestSite
, which derives the
site name and domain from the current
HttpRequest
.site_name
: An alias for site.name
. If you don’t have the site
framework installed, this will be set to the value of
request.META['SERVER_NAME']
.
For more on sites, see “sites” 프레임워크.logout_then_login
(request, login_url=None)¶Logs a user out on POST
requests, then redirects to the login page.
URL name: No default URL provided
Optional arguments:
login_url
: The URL of the login page to redirect to.
Defaults to settings.LOGIN_URL
if not supplied.버전 4.1부터 폐지됨: Support for logging out on GET
requests is deprecated and will be
removed in Django 5.0.
PasswordChangeView
¶URL name: password_change
Allows a user to change their password.
Attributes:
template_name
¶The full name of a template to use for displaying the password change
form. Defaults to registration/password_change_form.html
if not
supplied.
success_url
¶The URL to redirect to after a successful password change. Defaults to
'password_change_done'
.
form_class
¶A custom “change password” form which must accept a user
keyword
argument. The form is responsible for actually changing the user’s
password. Defaults to
PasswordChangeForm
.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
Template context:
form
: The password change form (see form_class
above).PasswordChangeDoneView
¶URL name: password_change_done
The page shown after a user has changed their password.
Attributes:
template_name
¶The full name of a template to use. Defaults to
registration/password_change_done.html
if not supplied.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
PasswordResetView
¶URL name: password_reset
Allows a user to reset their password by generating a one-time use link that can be used to reset the password, and sending that link to the user’s registered email address.
This view will send an email if the following conditions are met:
User.is_active
is True
).set_unusable_password()
) aren’t
allowed to request a password reset to prevent misuse when using an
external authentication source like LDAP.If any of these conditions are not met, no email will be sent, but the
user won’t receive any error message either. This prevents information
leaking to potential attackers. If you want to provide an error message in
this case, you can subclass
PasswordResetForm
and use the
form_class
attribute.
참고
Be aware that sending an email costs extra time, hence you may be vulnerable to an email address enumeration timing attack due to a difference between the duration of a reset request for an existing email address and the duration of a reset request for a nonexistent email address. To reduce the overhead, you can use a 3rd party package that allows to send emails asynchronously, e.g. django-mailer.
Attributes:
template_name
¶The full name of a template to use for displaying the password reset
form. Defaults to registration/password_reset_form.html
if not
supplied.
form_class
¶Form that will be used to get the email of the user to reset the
password for. Defaults to
PasswordResetForm
.
email_template_name
¶The full name of a template to use for generating the email with the
reset password link. Defaults to
registration/password_reset_email.html
if not supplied.
subject_template_name
¶The full name of a template to use for the subject of the email with
the reset password link. Defaults to
registration/password_reset_subject.txt
if not supplied.
token_generator
¶Instance of the class to check the one time link. This will default to
default_token_generator
, it’s an instance of
django.contrib.auth.tokens.PasswordResetTokenGenerator
.
success_url
¶The URL to redirect to after a successful password reset request.
Defaults to 'password_reset_done'
.
from_email
¶A valid email address. By default Django uses the
DEFAULT_FROM_EMAIL
.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
html_email_template_name
¶The full name of a template to use for generating a text/html multipart email with the password reset link. By default, HTML email is not sent.
extra_email_context
¶A dictionary of context data that will be available in the email
template. It can be used to override default template context values
listed below e.g. domain
.
Template context:
form
: The form (see form_class
above) for resetting the user’s
password.Email template context:
email
: An alias for user.email
user
: The current User
,
according to the email
form field. Only active users are able to
reset their passwords (User.is_active is True
).site_name
: An alias for site.name
. If you don’t have the site
framework installed, this will be set to the value of
request.META['SERVER_NAME']
.
For more on sites, see “sites” 프레임워크.domain
: An alias for site.domain
. If you don’t have the site
framework installed, this will be set to the value of
request.get_host()
.protocol
: http or httpsuid
: The user’s primary key encoded in base 64.token
: Token to check that the reset link is valid.Sample registration/password_reset_email.html
(email body template):
Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol}}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
The same template context is used for subject template. Subject must be single line plain text string.
PasswordResetDoneView
¶URL name: password_reset_done
The page shown after a user has been emailed a link to reset their
password. This view is called by default if the PasswordResetView
doesn’t have an explicit success_url
URL set.
참고
If the email address provided does not exist in the system, the user is inactive, or has an unusable password, the user will still be redirected to this view but no email will be sent.
Attributes:
template_name
¶The full name of a template to use. Defaults to
registration/password_reset_done.html
if not supplied.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
PasswordResetConfirmView
¶URL name: password_reset_confirm
Presents a form for entering a new password.
Keyword arguments from the URL:
uidb64
: The user’s id encoded in base 64.token
: Token to check that the password is valid.Attributes:
template_name
¶The full name of a template to display the confirm password view.
Default value is registration/password_reset_confirm.html
.
token_generator
¶Instance of the class to check the password. This will default to
default_token_generator
, it’s an instance of
django.contrib.auth.tokens.PasswordResetTokenGenerator
.
post_reset_login
¶A boolean indicating if the user should be automatically authenticated
after a successful password reset. Defaults to False
.
post_reset_login_backend
¶A dotted path to the authentication backend to use when authenticating
a user if post_reset_login
is True
. Required only if you have
multiple AUTHENTICATION_BACKENDS
configured. Defaults to
None
.
form_class
¶Form that will be used to set the password. Defaults to
SetPasswordForm
.
success_url
¶URL to redirect after the password reset done. Defaults to
'password_reset_complete'
.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
reset_url_token
¶Token parameter displayed as a component of password reset URLs.
Defaults to 'set-password'
.
Template context:
form
: The form (see form_class
above) for setting the new user’s
password.validlink
: Boolean, True if the link (combination of uidb64
and
token
) is valid or unused yet.PasswordResetCompleteView
¶URL name: password_reset_complete
Presents a view which informs the user that the password has been successfully changed.
Attributes:
template_name
¶The full name of a template to display the view. Defaults to
registration/password_reset_complete.html
.
extra_context
¶A dictionary of context data that will be added to the default context data passed to the template.
redirect_to_login
(next, login_url=None, redirect_field_name='next')¶Redirects to the login page, and then back to another URL after a successful login.
Required arguments:
next
: The URL to redirect to after a successful login.Optional arguments:
login_url
: The URL of the login page to redirect to.
Defaults to settings.LOGIN_URL
if not supplied.redirect_field_name
: The name of a GET
field containing the
URL to redirect to after log out. Overrides next
if the given
GET
parameter is passed.If you don’t want to use the built-in views, but want the convenience of not
having to write forms for this functionality, the authentication system
provides several built-in forms located in django.contrib.auth.forms
:
참고
The built-in authentication forms make certain assumptions about the user model that they are working with. If you’re using a custom user model, it may be necessary to define your own forms for the authentication system. For more information, refer to the documentation about using the built-in authentication forms with custom user models.
AdminPasswordChangeForm
¶A form used in the admin interface to change a user’s password.
Takes the user
as the first positional argument.
AuthenticationForm
¶A form for logging a user in.
Takes request
as its first positional argument, which is stored on the
form instance for use by sub-classes.
confirm_login_allowed
(user)¶By default, AuthenticationForm
rejects users whose is_active
flag is set to False
. You may override this behavior with a custom
policy to determine which users can log in. Do this with a custom form
that subclasses AuthenticationForm
and overrides the
confirm_login_allowed()
method. This method should raise a
ValidationError
if the given user may
not log in.
For example, to allow all users to log in regardless of “active” status:
from django.contrib.auth.forms import AuthenticationForm
class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
def confirm_login_allowed(self, user):
pass
(In this case, you’ll also need to use an authentication backend that
allows inactive users, such as
AllowAllUsersModelBackend
.)
Or to allow only some active users to log in:
class PickyAuthenticationForm(AuthenticationForm):
def confirm_login_allowed(self, user):
if not user.is_active:
raise ValidationError(
_("This account is inactive."),
code="inactive",
)
if user.username.startswith("b"):
raise ValidationError(
_("Sorry, accounts starting with 'b' aren't welcome here."),
code="no_b_users",
)
PasswordChangeForm
¶A form for allowing a user to change their password.
PasswordResetForm
¶A form for generating and emailing a one-time use link to reset a user’s password.
send_mail
(subject_template_name, email_template_name, context, from_email, to_email, html_email_template_name=None)¶Uses the arguments to send an EmailMultiAlternatives
.
Can be overridden to customize how the email is sent to the user.
매개변수: |
|
---|
By default, save()
populates the context
with the
same variables that
PasswordResetView
passes to its
email context.
SetPasswordForm
¶A form that lets a user change their password without entering the old password.
UserChangeForm
¶A form used in the admin interface to change a user’s information and permissions.
BaseUserCreationForm
¶A ModelForm
for creating a new user. This is the
recommended base class if you need to customize the user creation form.
It has three fields: username
(from the user model), password1
,
and password2
. It verifies that password1
and password2
match,
validates the password using
validate_password()
, and
sets the user’s password using
set_password()
.
UserCreationForm
¶Inherits from BaseUserCreationForm
. To help prevent confusion with
similar usernames, the form doesn’t allow usernames that differ only in
case.
In older versions, UserCreationForm
didn’t save many-to-many
form fields for a custom user model.
In older versions, usernames that differ only in case are allowed.
The currently logged-in user and their permissions are made available in the
template context when you use
RequestContext
.
Technicality
Technically, these variables are only made available in the template
context if you use RequestContext
and the
'django.contrib.auth.context_processors.auth'
context processor is
enabled. It is in the default generated settings file. For more, see the
RequestContext docs.
When rendering a template RequestContext
, the
currently logged-in user, either a User
instance or an AnonymousUser
instance, is
stored in the template variable {{ user }}
:
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
This template context variable is not available if a RequestContext
is not
being used.
The currently logged-in user’s permissions are stored in the template variable
{{ perms }}
. This is an instance of
django.contrib.auth.context_processors.PermWrapper
, which is a
template-friendly proxy of permissions.
Evaluating a single-attribute lookup of {{ perms }}
as a boolean is a proxy
to User.has_module_perms()
. For example, to check if
the logged-in user has any permissions in the foo
app:
{% if perms.foo %}
Evaluating a two-level-attribute lookup as a boolean is a proxy to
User.has_perm()
. For example,
to check if the logged-in user has the permission foo.add_vote
:
{% if perms.foo.add_vote %}
Here’s a more complete example of checking permissions in a template:
{% if perms.foo %}
<p>You have permission to do something in the foo app.</p>
{% if perms.foo.add_vote %}
<p>You can vote!</p>
{% endif %}
{% if perms.foo.add_driving %}
<p>You can drive!</p>
{% endif %}
{% else %}
<p>You don't have permission to do anything in the foo app.</p>
{% endif %}
It is possible to also look permissions up by {% if in %}
statements.
For example:
{% if 'foo' in perms %}
{% if 'foo.add_vote' in perms %}
<p>In lookup works, too.</p>
{% endif %}
{% endif %}
When you have both django.contrib.admin
and django.contrib.auth
installed, the admin provides a convenient way to view and manage users,
groups, and permissions. Users can be created and deleted like any Django
model. Groups can be created, and permissions can be assigned to users or
groups. A log of user edits to models made within the admin is also stored and
displayed.
You should see a link to “Users” in the “Auth” section of the main admin index page. The “Add user” admin page is different than standard admin pages in that it requires you to choose a username and password before allowing you to edit the rest of the user’s fields.
Also note: if you want a user account to be able to create users using the Django admin site, you’ll need to give them permission to add users and change users (i.e., the “Add user” and “Change user” permissions). If an account has permission to add users but not to change them, that account won’t be able to add users. Why? Because if you have permission to add users, you have the power to create superusers, which can then, in turn, change other users. So Django requires add and change permissions as a slight security measure.
Be thoughtful about how you allow users to manage permissions. If you give a non-superuser the ability to edit users, this is ultimately the same as giving them superuser status because they will be able to elevate permissions of users including themselves!
User passwords are not displayed in the admin (nor stored in the database), but the password storage details are displayed. Included in the display of this information is a link to a password change form that allows admins to change user passwords.
12월 04, 2023