rest-framework之认证组件
一、认证简介
只有认证通过的用户才能访问指定的url地址,比如:查询课程信息,需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件
二、使用认证组件
MyAuth->写一个类MyAuthetication,继承BaseAuthentication
-写两个方法,一个是authenticate,一个是authenticate_header
-在authenticate方法中写认证逻辑,认证通过,返回空,认证不通过,抛异常
class MyAuthetication(BaseAuthentication):
# 重写这个方法
def authenticate(self, request):
# 认证相关
# 如果token信息放到请求头中,如何取?
# request._request.META
# token=request.META.get('token')
# 校验该次请求是否携带正确的token
# 取出token
token = request.GET.get('token')
# 校验该请求是否正确携带token
ret = models.UserToken.objects.filter(token=token).first()
if ret:
# 正常通过认证的用户
# ret.user 当前登录用户
return ret.user, token
else:
# 没有登录或者非法用户
raise AuthenticationFailed('您未通过验证')
def authenticate_header(self, request):
pass
views->{authentication_classes=[MyAuthetication]}
class BooksView(APIView):
# 认证:
authentication_classes = [MyAuthetication]
def get(self, request):
print(request.user)
print(request.auth)
return Response('ok')
# 登陆
class Login(APIView):
# 全局使用的局部禁用
authentication_classes = []
def post(self, request):
response = {'status': 100, 'msg': None}
name = request.data.get('name')
pwd = request.data.get('pwd')
user = models.User.objects.filter(name=name, pwd=pwd).first()
print(user)
if user:
token = uuid.uuid4()
models.UserToken.objects.update_or_create(user=user, defaults={'token': token})
response['msg'] = '登陆成功'
response['token'] = token
else:
response['status'] = 101
response['msg'] = '用户名或密码错误'
return Response(response)
三、全局使用
REST_FRAMEWORK={
"DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",]
}
四、源码学习
-APIView的dispach方法---》self.initial(request, *args, **kwargs)----》400行self.perform_authentication(request)
---》APIView的perform_authentication(request)----》request.user(request是新的request)
---->去Request类中找user,执行--->self._authenticate()(self是新的reqeust对象)---->Request类的_authenticate(self)方法,深度
#Request对象的user方法
@property
def user(self):
the authentication classes provided to the request.
if not hasattr(self, '_user'):
with wrap_attributeerrors():
self._authenticate()
return self._user
def _authenticate(self):
for authenticator in self.authenticators:
try:
user_auth_tuple = authenticator.authenticate(self)
except exceptions.APIException:
self._not_authenticated()
raise
#认证成功,可以返回一个元组,但必须是最后一个验证类才能返回
if user_auth_tuple is not None:
self._authenticator = authenticator
self.user, self.auth = user_auth_tuple
return
self._not_authenticated()
self.authenticators
def get_authenticators(self):
return [auth() for auth in self.authentication_classes]
五、小结
-最终的认证使用(按照这个来)******重点*******
-局部使用
-在视图类中配置:authentication_classes=[MyAuthetication]
-全局使用
-在setting中配置:REST_FRAMEWORK={'DEFAULT_AUTHENTICATION_CLASSES':['app01.MyAuth.MyAuthetication',]}
-全局使用了,局部禁用:
-在视图类中配置:authentication_classes=[]