django.contrib.auth의authenticate 함수 원본 분석
django는 사용자의 로그인과 권한 수여에 사용되는 기본auth시스템을 제공하고 일정한 확장성을 제공합니다. 개발자가 여러 개의 검증 백엔드를 스스로 정의할 수 있도록 합니다. 모든 검증 백엔드는 authenticate 함수를 실현하고 None이나 User 대상을 되돌려야 합니다.
기본 백그라운드는django입니다.contrib.auth.backends.ModelBackend, 이 백엔드는 사용자 이름과 비밀번호를 통해 사용자 인증을 하고 settings로 합니다.AUTH_USER_MODEL을 모델로 사용합니다.그러나 실제 개발에서 모두가 사용자 이름과 같은 모델을 고정적으로 사용하여 검증하지 않을 것이라고 믿는다. 예를 들어 서로 다른 역할은 서로 다른 모델을 검증하는 데이터 원천으로 하고 어떤 역할은 핸드폰으로 로그인하며 어떤 역할은 메일로 로그인한다.
그렇다면 여러 개의 검증 백엔드가 존재할 때django는 어떻게 통일된 인터페이스를 만들어 서로 다른 백엔드 검증을 합니까?
authenticate 함수 분석
소스:
def authenticate(**credentials):
""" If the given credentials are valid, return a User object. """
for backend, backend_path in _get_backends(return_tuples=True):
try:
inspect.getcallargs(backend.authenticate, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue
try:
user = backend.authenticate(**credentials)
except PermissionDenied:
# This backend says to stop in our tracks - this user should not be allowed in at all.
break
if user is None:
continue
# Annotate the user object with the path of the backend.
user.backend = backend_path
return user
# The credentials supplied are invalid to all backends, fire signal
user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials))
**credentials
우선authenticate 함수가 받아들이는 매개 변수를 볼 수 있습니다. 이것은authenticate 함수가 키워드만 받아들이고 위치는 허용하지 않는다는 것을 말합니다.따라서 authenticate 함수를 사용할 때 수고를 덜기 위해 위치에서 참조를 하지 않도록 주의하십시오.
# This will fail
user = authenticate('username', 'password')
# This will success
user = authenticate(username='username', password='password')
inspect.getcallargs(func, *args, **kwargs)
ppect 모듈은 파이톤의 공식 표준 모듈로 이 모듈은 파이톤의 자성 기능을 일정한 봉인을 한다.그중에 인스펙트.getcallargs는args와kwargs 이 매개 변수가func에서 요구하는 매개 변수와 일치하는지 검사합니다. 일치하지 않으면 매개 변수 사전을 되돌려줍니다. 일치하지 않으면 raise TypeError입니다.간단한 예를 들다.Python에서 다음과 같은 함수를 정의한다고 가정합니다.
import inspect
def test_func(arg1, arg2, *args, **kwargs):
pass
# this will raise TypeError
inspect.getcallargs(test_func, a=1, b=2, c=3)
# TypeError: test_func() missing 2 required positional arguments: 'arg1' and 'arg2'
# this will ok
inspect.getcallargs(test_func, 1, 2, 3, a=1, b=2, c=3)
# {'kwargs': {'b': 2, 'c': 3, 'a': 1}, 'arg2': 2, 'args': (3,), 'arg1': 1}
장면 적용
인스펙트를 통해서.getcallargs의 매개 변수 필터 기능은 서로 다른 백엔드의authenticate 함수 매개 변수를 설정하면 첫 번째 단계에서 서로 다른 역할의 백엔드 선택을 실현할 수 있습니다.
만약에 세 가지 캐릭터가 있다고 가정하면 캐릭터 1은 사용자 이름으로 로그인하고 캐릭터 2는 핸드폰으로 로그인하며 캐릭터 3은 핸드폰이나 메일로 로그인하면 어떻게 인스펙트를 통과할 것인가.getcallargs는 적합한 백엔드를 선택하십시오.authenticate는요?
def role3_authenticate(role3_phone=None, role3_email=None, password=None):
print("role1 authentication.")
def role2_authenticate(role2_phone=None, password=None):
print("role2 authenticate.")
def role1_authenticate(role1_name=None, password=None):
print("role2 authenticate.")
methods = [role1_authenticate, role2_authenticate, role3_authenticate]
def authenticate(**credentials):
for backend in methods:
try:
inspect.getcallargs(backend, **credentials)
except TypeError:
print("error")
continue
backend(**credentials)
print("end")
break
**kwargs를 추가하면 모든 authenticate가 TypeError를 일으키지 않습니다. 나머지 매개 변수는 기본 매개 변수를 설정했기 때문에 필요하면 이전의 매개 변수는 위치 참조를 사용합니다.
signal
만약 사용자가 로그인에 성공하지 못했다면, authenticate는 사용자가 로그인에 성공하지 못한 신호를 보냈고, 개발자는 이 신호를 받아들이는recevier를 스스로 정의할 수 있습니다.django signal에 관해서는 필자가 나중에 상세하게 이야기할 것이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Asp와 XML로 상호작용하는 실례 원본XML은 표준 확장 언어로 미래 웹 프로그래밍의 표준이다. asp는 현재 널리 전해지는 웹 프로그래밍 언어 중의 하나이다. 그들 두 사람이 연합하여 역할을 발휘할 수 있을까?두부는 여기서 여러분에게 아주 간단한 As...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.