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)
spect 모듈은 Python 공식적인 표준 모듈로 이 모듈은 Python의 자성 기능에 대해 일정한 봉인을 진행한다.그중 검사.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은 핸드폰이나 메일박스로 로그인하면 어떻게 inspect를 통과합니까?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를 스스로 정의할 수 있습니다.djangosignal에 관해서는 필자는 이후에 상세하게 이야기할 것이다.
이상은 본문의 전체 내용입니다. 여러분의 학습에 도움이 되고 저희를 많이 응원해 주십시오.

좋은 웹페이지 즐겨찾기