Django의 사용자 모듈 및 권한 시스템
좋은 사용자 시스템을 설계하는 것은 흔히 쉽지 않다. Django가 제공하는 사용자 시스템은 기본적인 기능을 신속하게 실현할 수 있고 이를 바탕으로 우리의 수요를 만족시키기 위해 계속 확장할 수 있다.
먼저 Django의 사용자 시스템이 제공하는 기능을 살펴보겠습니다.
1. 로그인
# some_view.py
from django.contrib.auth import authenticate, login
def login(request):
username = request.POST['username']
password = request.POST['password']
# Django authenticate ,
user = authenticate(username=username, password=password)
if user is not None:
# Django login , key
login(request, user)
# ,
...
else:
#
...
2. 로그아웃
# some_view.py
from django.contrib.auth import logout
def logout(request):
# logout
logout(request)
3. 로그인 여부 확인
# some_view.py
def some_fuction(request):
user = request.user
if user.is_authenticated:
# ,
else:
#
4. 권한이 있는지 확인
# some_view.py
def some_fuction(request):
user = request.user
if user.has_perm('myapp.change_bar'):
# ,
else:
#
사용자 모듈
Django의 사용자 모듈 클래스는 auth 응용 프로그램에 정의됩니다. 예를 들어 Django의 사용자 클래스를 직접 사용하려면 setting 설정 파일의 INSTALL APP에 한 줄
django.contrib.auth
을 추가합니다.이렇게 하면 코드에서 User 클래스로 사용자를 직접 만들 수 있습니다.
from django.contrib.auth.models import User
user = User.objects.create_user('john', '[email protected]', 'johnpassword')
user.last_name = 'Lennon'
user.save()
Django의 소스 User 클래스에 정의된 속성에 대해 살펴보십시오.
class User(AbstractUser):
"""
Users within the Django authentication system are represented by this
model.
Username, password and email are required. Other fields are optional.
"""
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
..., 아무것도 없나?
User 클래스는 AbstractUser 클래스를 계승하고 사용자 이름과 비밀번호 정보 등이 부모 클래스에 정의되어 있음을 알 수 있습니다.그래서 AbstractUser 클래스의 정의를 다시 한 번 봅시다. 편폭에 따라 그 중 일부만 열거하고 원본 코드는https://github.com/django/django/blob/master/django/contrib/auth/models.py
class AbstractUser(AbstractBaseUser, PermissionsMixin):
username = models.CharField(
_('username'),
max_length=150,
unique=True,
help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
validators=[username_validator],
error_messages={
'unique': _("A user with that username already exists."),
},
)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
email = models.EmailField(_('email address'), blank=True)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
....
AbstractUser 클래스에서username이 정의된 필드를 볼 수 있으며 이메일,first 도 있습니다name、last_name 등AbstractUser 클래스는 AbstractBaseUser와PermissionsMixin 클래스를 계승하고, AbstractBaseUser 클래스는password 필드와 비밀번호를 암호화하여 저장하는 방법을 제공하며, PermissionsMixin 클래스는 User 클래스 권한 인증 기능을 제공합니다.
전반적으로 User 클래스는 다음 필드를 정의합니다.
User 클래스는 다음과 같은 다양한 방법을 제공합니다.
사용자 이름과 비밀번호를 검증하는 것은 매우 간단해 보이지만 제출한 사용자 이름과 비밀번호가 데이터베이스에 저장된 것과 일치하도록 비교하면 된다.
예:
# some_view.py
def some_fuction(request):
username = request.POST['username']
password = request.POST['password']
try:
user = User.objects.get(username=username, password=password)
except ObjectNotExists:
#
...
비밀번호가 이미hash 후에 저장되었기 때문에 상술한 코드는 제출한password값을 먼저hash 다음에 데이터베이스에서 검색해야 하기 때문에 반드시 코드를 좀 더 써야 한다.이러한 Django는 가이드의 인스턴스 코드와 같이 authenticate 함수를 사용하여 사용자가 있는지 확인할 수 있습니다.
# some_view.py
from django.contrib.auth import authenticate, login
def login(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
...
else:
...
여기에 authenticate와login 함수를 중점적으로 설명한다.
1.
authenticate(**credentials)
검증할 인자를 전송합니다. 기본값은username과password입니다. 시스템 설정에 있는 모든
authentication backend
을 호출하여 검증합니다. 검증은 User 실례를 되돌려줍니다. 그렇지 않으면 None을 되돌려줍니다.각각
authentication backend
은 인증 백엔드를 가리키며 setting에 있습니다.py에서 구성된 AUTHENTICATIONBACKENDS 변수는 기본적으로 ['django.contrib.auth.backends.ModelBackend']로 사용자 정의 인증 백엔드를 추가하거나 제3자가 제공하는 것을 사용할 수 있습니다.authenticate 함수는 모든 인증을 순서대로 호출합니다. 첫 번째 인증이 통과되지 않으면 두 번째 인증을 사용하여 모든 인증 백엔드가 실패한 후에야 None으로 돌아갑니다.이 ModelBackend 클래스가 인증 사용자에게 어떻게 되돌아오는지 보십시오. (원본 코드를 다시 줄입니다.)
class ModelBackend(object):
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
# ...
실제로 authenticate 함수는 모든
authentication backend
클래스의 authenticate 방법을 호출합니다.ModelBackend 클래스는 이전의 검증 방법과 약간 다르기 때문에 데이터베이스 사용자 테이블에서username에 대응하는 User 실례를 꺼내고 User의 check 를 통과합니다.password 방법은 password가 정확한지 확인하고 이 User 실례를 되돌려줍니다.2.
login(request, user, backend=None)
Http Request 대상과 User 대상을 받으면login 함수는 현재 사용자 정보를 세션 쿠키에 저장하기 때문에 Django 사용자 시스템의 모든 기능을 사용하려면 Django 기본 세션 앱을 설치해야 합니다.
login 함수가 무엇을 했는지 보십시오:
def login(request, user, backend=None):
# ( session )
# ...
request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = backend
request.session[HASH_SESSION_KEY] = session_auth_hash
if hasattr(request, 'user'):
request.user = user
rotate_token(request)
user_logged_in.send(sender=user.__class__, request=request, user=user)
login 함수는 현재 사용자의 유일한 표지 정보를 Request에 저장합니다.session
SESSION_KEY
에서 다음 요청 시 세션 쿠키에서 현재 로그인한 사용자 대상을 받을 수 있습니다.적절한 View에 액세스하기 위해 로그인이 필요한 경우 다음과 같이 쓸 수 있습니다.
from django.conf import settings
from django.shortcuts import redirect
def my_view(request):
if not request.user.is_authenticated:
return redirect('%s?next=%s' % (settings.LOGIN_URL, request.path))
login 함수를 통해 사용자 정보를 세션에 저장할 수 있습니다. 현재 요청이view에 도착하기 전에 Django의 세션 중간부품은 세션 쿠키에서 사용자 대상을 추출하고 Request에 값을 부여합니다.user.이렇게 하면 로그인한 사용자 Request.user.is_authenticated 값은 True이며 적절한 작업을 수행할 수 있습니다.로그인하지 않은 사용자 request.user가 is AnonymousUser 객체를 반환합니다.authenticated 속성 값은 영원히 False입니다. 이 요청을 로그인 페이지로 다시 지정해야 합니다.
이 두 줄 코드는view 함수에 장식기를 추가하여 실현할 수 있습니다. 예를 들어
@login_required
def my_view(request):
...
장식기
login_required(redirect_field_name='next', login_url=None)
,login 전송 가능url 파라미터는 로그인하지 않은 사용자의 요청 방향을 바꾸는 주소를 설정합니다. 그렇지 않으면settings로 변경합니다.LOGIN_URL. 네 가지 권한 인증
User 모델에는 두 개의 다중 관계 필드가 있습니다:groups와userpermissions - Pemission 모델과 관련이 있습니다.User와 Pemission, User와 Permission, Group과 Permission은 모두 다대다관계이다. Permission은 구체적인 권한을 정의하고 그 필드는 다음과 같다.
class Permission(models.Model):
name = models.CharField(_('name'), max_length=255) # ( )
content_type = models.ForeignKey( # : ,
ContentType,
models.CASCADE,
verbose_name=_('content type'),
)
codename = models.CharField(_('codename'), max_length=100) # , has_permission
사용자에게 권한을 추가하고 삭제하는 것은 간단합니다: myuser.user_permissions.set([permission_list]) myuser.user_permissions.add(permission, permission, …) myuser.user_permissions.remove(permission, permission, …) myuser.user_permissions.clear()
그 중에서 퍼미션은 구체적인 퍼미션 대상이다.사용자가 있는 그룹을 통해 그룹 권한을 추가할 수도 있습니다.permissions.set([permission_list]) group.permissions.add(permission, permission, …) group.permissions.remove(permission, permission, …) group.permissions.clear()
이 사용자가 이 그룹에 가입하기만 하면 그룹 권한도 있습니다.User 객체의 get 을 통해all_permissions(obj=None) 방법은 이 사용자의 모든 권한 목록(문자 목록)을 얻을 수 있고 get 을 통해group_permissions(obj=None)는 해당 그룹 권한 목록을 가져옵니다.
우리가 더 자주 해야 할 일은view에서 작업을 실행하기 전에 사용자가 지정한 권한을 가지고 있는지 확인하는 것입니다. 여기에는 User 대상의
has_perm(perm, obj=None)
방법이나 has_perms(perm_list, obj=None)
판단이 사용됩니다.has_perm(perm, obj=None)
방법 중perm
은'입니다."형식의 권한 문자열. 이 권한이 있으면 방법은 True로 돌아갑니다. 마찬가지로 'has perms (perm list, obj=None)' 방법에서perm list는 '입니다."형식의 권한 문자열 목록입니다.동loginrequired 장식기, 권한 인증에 대응하는permissionrequired 장식기:
permission_required(perm, login_url=None, raise_exception=False)
하면, 만약, 만약...exception=True, 권한이 인증되지 않으면 PermissionDenied 이상을 던지고 기본 403페이지를 되돌려줍니다.
Done.
원본 주소:http://neven.me/django/2016/11/26/Django%E7%9A%84%E7%94%A8%E6%88%B7%E6%A8%A1%E5%9D%97%E4%B8%8E%E6%9D%83%E9%99%90%E7%B3%BB%E7%BB%9F/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.