1.相关配置
# project/urls.py
from rest_framework_jwt.views import obtain_jwt_token
urlpatterns = [
...
path('login/', obtain_jwt_token),
]
# project/setting.py
AUTHENTICATION_BACKENDS = (
'users.views.CustomBackend', #自定义手机号密码登陆
'social_core.backends.weibo.WeiboOAuth2', #第三方登录
'django.contrib.auth.backends.ModelBackend' # 默认的验证登陆
)
2.源码分析
- restframework_jwt/view.py
按住Ctrl进入JSONWebTokenAPIView
按Ctrl进入JSONWebTokenSerializer
进入authenticate(**credentials)
源码如下
def authenticate(request=None, **credentials):
"""
调用_get_backends()对AUTHENTICATION_BACKENDS做循环遍历验证
验证成功返回user
"""
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:
# 调用该自定义验证的authenticate方法
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)
_get_backends()
源码
def _get_backends(return_tuples=False):
backends = []
"""
循环AUTHENTICATION_BACKENDS
"""
for backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
backends.append((backend, backend_path) if return_tuples else backend)
if not backends:
raise ImproperlyConfigured(
'No authentication backends have been defined. Does '
'AUTHENTICATION_BACKENDS contain anything?'
)
return backends