django-restfulframework认证源码解析
认证控制:检查用户是否登录,或携带某些元素.
当程序运行时,首先会调用程序的self.dispatch
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def dispatch(self, request, *args, **kwargs): self.args = args self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) # 第一步 self.request = request self.headers = self.default_response_headers # 第二部 try: self.initial(request, *args, **kwargs) #第三步 # Get the appropriate handler method if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response
第一步:调用initialize_request函数.封装了request,并且返回一个Request的对象,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def initialize_request(self, request, *args, **kwargs): parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), #[parser() for parser in self.parser_classes]对象的列表 authenticators=self.get_authenticators(), #同上都是返回对象列表 negotiator=self.get_content_negotiator(), #同上 parser_context=parser_context )
第二部:调用 default_response_headers返回抱头,里面包含请求信息,形成的样式
headers={'Allow':['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'],}
@property def default_response_headers(self): headers = { 'Allow': ', '.join(self.allowed_methods), } if len(self.renderer_classes) > 1: #如果配置有信息,会加上{'Vary':"Accept"} headers['Vary'] = 'Accept' return headers
第三步: 调用initial,检查用户版本,用户认证,权限验证,以及访问频率的控制.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def initial(self, request, *args, **kwargs): self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) #版本控制 request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted self.perform_authentication(request) #用户认证 self.check_permissions(request) #权限验证 self.check_throttles(request) #访问频率控制
分析用户认证:
1) 运行self.perform_authentication(request),返回request.user
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def perform_authentication(self, request):
request.user #此刻的request是 Request
2)找到Request,并且运行user方法.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@property def user(self): if not hasattr(self, '_user'): #程序刚开始运行,没有用户登录,所以会执行这里 with wrap_attributeerrors(): self._authenticate() return self._user
3) 调用self._authenticate()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def _authenticate(self): for authenticator in self.authenticators: #第4)步 实例化class ForcedAuthentication(object) try: user_auth_tuple = authenticator.authenticate(self) #第5)步调用authenticate except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator #第6步返回上面调用的东西 self.user, self.auth = user_auth_tuple return #第7步如果有东西传进来就return self._not_authenticated()
4)调用self.authenticators等于实例化 ForcedAuthentication类:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class ForcedAuthentication(object): def __init__(self, force_user, force_token): self.force_user = force_user self.force_token = force_token def authenticate(self, request): return (self.force_user, self.force_token)
5)执行user_auth_tuple = authenticator.authenticate(self)也就是
ForcedAuthentication下面的authenticate方法:
def authenticate(self, request): return (self.force_user, self.force_token
返回里面的2个参数,参数可以自己定义,你传进去什么就是什么
6)返回self._authenticator = authenticator,这里能拿到数据必须是用user和auth才能拿
self.user, self.auth = user_auth_tuple