rest_framework-01-认证(用户登录)-内置认证
rest_framework-01-认证(用户登录)-内置认证
如果我们写API有人能访问,有人不能访问,则需要些认证。
如何知道该用户是否已登入?
如果用户登入成功,则给用户一个随机字符串,去访问另一个页面。
以前写session的时候,都是把session写cookie里面。
那现在我们可以把随机字符串通过返回值的方式给用户。
后端通过查看用户的url判断用户有没有token值且这个字符串是否正确也要判断。有则已登入,可以访问;没有则跳回登入页面。
用户登入
1.有些api需要用户登入才能访问,有些api不需要用户登入就能访问。
1.api(app应用) > models.py: 表

2.创建表数据:用户表

3.urls.py

4.views.py:用户登入只有post请求!!!

5.token用md5加密,并保存或更新到数据库中。


6.post请求,运行结果:

7.token就保存到数据库了。

8.token生成成功后,就将新的token返回给用户。有异常则返回异常。API写完了。

views.py:API写完了。

运行结果:

小结:解决: a. 创建两张表 。b. 用户登录(返回token并保存到数据库)。
认证
用户所有订单api
1.订单url

2.views.py订单视图
假设这是所有订单数据


3.运行结果:get请求

4.如果这个订单只有登入成功的时候才可以看,你会怎么解决???

运行结果:

rest_framework认证
5.这段代码假设post请求也要认证,如果再复制一遍就会很冗余。django已经帮我们封装好了,不用自己写。

6.自定义一个认证类,自己写认证规则。

7.认证源码:

8.自己定义认证规则,认证失败则返回一个异常。


9.注意:必须再写一个方法,否则还会报错。
引入该模块, 加上该方法:先为空。

查看该模块源码:

加上该方法:先为空。

注释一下代码:

运行结果:

用户信息api
1.假设用户信息api也要认证,(登入后才能访问),怎么办呢?
自定义的一个认证写完了之后,api视图加上就好了。

2.如果有成千上万个api都需要认证怎么办呢??? 接下来全局认证。(不需要每一个视图都自己加上以上代码)全局配置settings.py。
认证源码流程图:

源码配置:
1.dispatch

2.封装Request

3.for循环认证列表

4.默认去全局的配置文件读

5.如果自己请求函数里面设置了,就用自己的。没设置就用配置文件的。
6.将认证写在配置文件中,不用局部的。
源码:
api_settings表示去配置文件中读。

读 REST_FRAMEWORK 这个key

7.setting.py

8.将认证相关的东西都写在一个文件中。再引入该文件。

settings.py
REST_FRAMEWORK = { # 全局使用的认证类 "DEFAULT_AUTHENTICATION_CLASSES":['api.utils.auth.FrstAuthtication','api.utils.auth.Authtication'], }
views.py:视图文件中只有视图相关的类。

9.列表里填你自己写的认证类的路径。 view.py里的所有类都不用加了,默认用session全局的认证。

10.登入不需要认证信息。全局认证,个别不需要认证。
空列表就行

11.运行结果:
订单接口:

登入接口:

订单接口:

request封装完了(认证配置),接下来继续看源码。
0.request封装

1.读取全局认证配置

2.进行认证

3.initial > 实现认证self.perform_authentication(request)

4.user

5.获取认证对象,进行下一步步的认证

往下走


6.如果是匿名用户,默认叫什么
setting.py

views.py

urls.py

运行结果:

7.源码设置默认用户名:

8.设置匿名用户名
"UNAUTHENTICATED_USER":lambda :"匿名用户"
匿名函数没有参数,直接返回字符串

url请求:

运行结果:

9.setting.py:


内置认证
1.django内置的认证在哪呢?引入BaseAuthentication
from rest_framework.authentication import BaseAuthentication

BaseAuthentication源码:
1.

2.BaseAuthentication 下有两个方法。

3.推荐继承BaseAuthentication。更规范。

代码:
from rest_framework import exceptions from api import models from rest_framework.authentication import BaseAuthentication # 用户认证 class FrstAuthtication(BaseAuthentication): def authenticate(self,request): pass def authenticate_header(self, request): pass class Authtication(BaseAuthentication): def authenticate(self,request): token = request._request.GET.get('token') token_obj = models.UserToken.objects.filter(token=token).first() if not token_obj: # 未登入或者是错误的token raise exceptions.AuthenticationFailed('用户认证失败!') # 认证成功。在rest_framework内部会将整个两个字段赋值给request,以供后续操作使用。 return (token_obj.user,token_obj) def authenticate_header(self, request): pass
接下来继续走源码: BasicAuthentication 基于留言器认证

1.往下走,复制源码

2.设置请求头的返回值为api

settings.py

运行结果:

3.views.py: 引入BasicAuthentication

4.运行结果:

5.看源码

6.改源码,先注释一下2行代码

不注释表示允许用户为匿名用户。

7.运行结果:浏览器会对用户名和密码加密放到url上,然后发给服务端,进行验证。

8.还原代码:

BasicAuthentication原理:

小结:
今日内容: 1. 认证 a. 问题1:有些API需要用户登录成功之后,才能访问;有些无需登录就能访问。 b. 基本使用认证组件 解决: a. 创建两张表 b. 用户登录(返回token并保存到数据库) c. 认证流程原理 - 见图示 d. 再看一遍源码 1. 局部视图使用&全局使用 2. 匿名是request.user = None e. 内置认证类 1. 认证类,必须继承:from rest_framework.authentication import BaseAuthentication 2. 其他认证类:BasicAuthentication 梳理: 1. 使用 - 创建类:继承BaseAuthentication; 实现:authenticate方法 - 返回值:3种返回值 - None,我不管了,下一认证来执行。 - raise exceptions.AuthenticationFailed('用户认证失败') # from rest_framework import exceptions - (元素1,元素2) # 元素1赋值给request.user; 元素2赋值给request.auth - 局部使用 from rest_framework.authentication import BaseAuthentication,BasicAuthentication class UserInfoView(APIView): """ 订单相关业务 """ authentication_classes = [BasicAuthentication,] def get(self,request,*args,**kwargs): print(request.user) return HttpResponse('用户信息') - 全局使用: REST_FRAMEWORK = { # 全局使用的认证类 "DEFAULT_AUTHENTICATION_CLASSES":['api.utils.auth.FirstAuthtication','api.utils.auth.Authtication', ], # "UNAUTHENTICATED_USER":lambda :"匿名用户" "UNAUTHENTICATED_USER":None, # 匿名,request.user = None "UNAUTHENTICATED_TOKEN":None,# 匿名,request.auth = None } 2. 源码流程 - dispatch - 封装request - 获取定义的认证类(全局/局部),通过列表生成时创建对象。 - initial - perform_authentication request.user(内部循环....)

浙公网安备 33010602011771号