背景
Djangoのバージョンを1.11.1
から2.2
へアップデート中、
自分でカスタマイズさせといたauthenticationでエラーが出るようになった。
django1.11.1のauthenticate
def authenticate(request=None, **credentials):
"""
If the given credentials are valid, return a User object.
"""
for backend, backend_path in _get_backends(return_tuples=True):
try:
user = _authenticate_with_backend(backend, backend_path, request, 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), request=request)
def _authenticate_with_backend(backend, backend_path, request, credentials):
args = (request,)
# Does the backend accept a request argument? <---このコメント何。
try:
inspect.getcallargs(backend.authenticate, request, **credentials)
except TypeError:
args = ()
credentials.pop('request', None)
# Does the backend accept a request keyword argument?
try:
inspect.getcallargs(backend.authenticate, request=request, **credentials)
except TypeError:
# Does the backend accept credentials without request?
try:
inspect.getcallargs(backend.authenticate, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
return None
else:
warnings.warn(
"Update %s.authenticate() to accept a positional "
"`request` argument." % backend_path,
RemovedInDjango21Warning
)
else:
credentials['request'] = request
warnings.warn(
"In %s.authenticate(), move the `request` keyword argument "
"to the first positional argument." % backend_path,
RemovedInDjango21Warning
)
return backend.authenticate(*args, **credentials)
↓自分で作ったauthentication
from django.contrib.auth.backends import ModelBackend
from .models import UserProfile
class SignedRequestBackend(ModelBackend):
"""認証を別途行うため、素通りの認証バックエンドを実装"""
def authenticate(self, user=None, user_profile=None, **kwds):
if user is None:
return
if not user.is_authenticated or not user.is_active:
return
if municipality_user_profile is None:
return
if not isinstance(user_profile, UserProfile):
return
if user.id != user_profile.user_id:
return
return user
django2.2のauthenticate
def authenticate(request=None, **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, request, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue
try:
user = backend.authenticate(request, **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), request=request)
【結論】 _authenticate_with_backend functionが廃止されてます。
inspect.getcallargsをデバッグしてみたところ
【エラー原因】 argsに['self', 'user', 'user_profile']って代入される(ここには['self', 'request']と入ってほしい)
- あ、なんかコメントあったな...
# Does the backend accept a request argument?
- 自分で作ったauthenticationの引数に
request
を設定 → エラーが解決されました。