> 官方原文链接
纳尼,你居然敢说看不懂???
REST framework 的 Request
类扩展与标准的 HttpRequest
,并做了相应的增强,比如更加灵活的请求解析(request parsing)和认证(request authentication)。
认证(Authentication)
REST framework 提供了灵活的认证方式:
- 可以在 API 的不同部分使用不同的认证策略。
- 支持同时使用多个身份验证策略。
- 提供与传入请求关联的用户(user)和令牌(token)信息。
.user
request.user
通常会返回 django.contrib.auth.models.User
的一个实例,但其行为取决于正在使用的身份验证策略。
如果请求未经身份验证,则 request.user
的默认值是 django.contrib.auth.models.AnonymousUser
的实例(就是匿名用户)。
关于 .user
的更多内容,以后再说~
.auth
request.auth
返回任何附加的认证上下文(authentication context)。request.auth
的确切行为取决于正在使用的身份验证策略,但它通常可能是请求经过身份验证的令牌(token)实例。
如果请求未经身份验证,或者没有附加上下文(context),则 request.auth
的默认值为 None
。
关于 .auth
的更多内容,以后再说~
.authenticators
APIView
类或 @api_view
装饰器将确保根据视图上设置的 authentication_classes
或基于 settings
文件中的 DEFAULT_AUTHENTICATORS
设置将此属性(.authenticators
)自动设置为 Authentication
实例列表。
**通常不需要关注该属性… **
注意:调用
.user
或.auth
属性时可能会引发WrappedAttributeError
异常。
这些错误源于 authenticator 作为一个标准的AttributeError
,为了防止它们被外部属性访问修改,有必要重新提升为不同的异常类型。Python 无法识别来自 authenticator 的AttributeError
,并会立即假定请求对象没有.user
或.auth
属性。authenticator 需要修复。
认证实现过程
下面是我总结的精简流程:
django 的url请求对应一个视图函数as_view函数,其中调用rest_framework/views.py中的dispatch函数,这个函数会根据request的请求方法,去调用我们在view对象中定义的对应的方法:
urlpatterns = [
url(
r"^test/?", testView.as_view(),
)]
testView是继承APIView的View类:
class TestView(APIView):
authentication_classes = (
BasicAuthentication,
SessionAuthentication,
TokenAuthentication,
)
permission_classes = (
IsAuthenticated,
)
def get(self,request):
pass
如果是get请求会调用as_view中的dispatch方法,dispatch根据request.Method调用
对应的get的方法,url->视图函数
权限认证是在dispatch中做的
self.as_view()
||
vv
def dispatch(request,*args,**kwargs):
||
VV
self.initial(request,*args,**kwargs):
||
VV
self.perform_authentication
self.check_permissions
self.check_throttles
验证某个用户:
perform_authentication(request)
request.user
request.user其实是一个@property函数
里面有个self._authenticate()方法
_authenticate(self)方法中验证用户就是authenticator.authenticate(self)
**self.authenticators从哪里来?**
就是从视图函数中的authentication_classes中的来,关于对view控制的其他类都在rest_framework/views.py的APIView类中定义了。
在BasicAuthentication中必须实现authenticate方法,并且返回一个用户,并赋值给request.user,这个request.user就是系统中进行用户认证的user对象,后续的权限认证
就是通过该user为依据进行判断是否有某个api的权限!
user = authenticate(**credentials)
||
vv
user = backend.authenticate(**credentials)
这个authenticate是django的authenticate方法:
||
vv
主要是去数据库校验数据,校验结束!!!
接着执行self.check_permissions(self,request):
如果权限不通过,那么会执行self.permission_denied,然后这个异常会在dispatch
函数中被捕捉,当做结果传递给response。
当一次授权通过后,再一次访问这个API时,用户名密码从哪来?
cookie和session
多说几句:
.authenticators
其实存的就是当前使用的认证器(authenticator)列表,打印出来大概是这样:
[<rest_framework.authentication.SessionAuthentication object at 0x7f8ae4528710>, <rest_framework.authentication.BasicAuthentication object at 0x7f8ae45286d8>]
可以看到这里使用的认证器(authenticator)包括 SessionAuthentication
和 BasicAuthentication
。