三大认证
django转换器,配置文件作用
# django转换器:django 2.x以后,为了取代 re_path
int
str
path
uuid
slug
# 后俩不常用
实际用法: path('index/<int:id>',view.index)
# django配置文件
1 djagno项目要运行,优先执行配置文件的内容,做一下配置加载工作
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'drf_day07.settings')
2 任何一个django项目都有两套配置:
-一套是项目自己的,自己有那个配置参数,优先用自己的
-一套是内置的(django内置的)
2 配置参数的作用
# pathlib 模块,处理路径
配置文件
from pathlib import Path
# 1 项目的根路径
BASE_DIR = Path(__file__).resolve().parent.parent
# 2 密钥---》djagno中涉及到加密的,大部分都会用这个密钥
SECRET_KEY = 'django-insecure-eh=o(kt_70%8wj4r+le-7*$7t+fn%_2rfh61f09(2^&3q-5vk)'
# 3 是否开启调试模式,上线一定关闭
# 只要是调试模式:
# 访问的路径不存在,他会显示出所有能访问的路径
# 视图类出了异常,浏览器中能看到
DEBUG = False
# 4 项目是要部署在某个服务器上,这个列表写,部署服务器的ip地址, * 表示任意地址都可以
ALLOWED_HOSTS = ['*']
# 5 内置,我们自己写的app
from django.contrib import auth
INSTALLED_APPS = [
'django.contrib.admin', # 后台管理---》很多表不是它的,是别的app的
'django.contrib.auth', # auth 模块,UsrInfo表----》有6个表
'django.contrib.contenttypes', # 有个django_content_type表是,这个app的
'django.contrib.sessions', # session相关的
'django.contrib.messages', # 消息框架
'django.contrib.staticfiles', # 静态文件开启的app
'app01.apps.App01Config', # app01
'rest_framework' # drf
]
# 6 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', # session相关
'django.middleware.common.CommonMiddleware', # 公共
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 7 根路由
ROOT_URLCONF = 'drf_day07.xxx'
# 8 模板文件所在路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'], # 必须是个列表
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
# 9 项目上线,运行application,后面再说
WSGI_APPLICATION = 'drf_day07.wsgi.application'
# 10 数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# 密码认证相关,忽略
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# 11 做国际化
LANGUAGE_CODE = 'zh-hans'
# 改语言的https://blog.csdn.net/bb_nie/article/details/107064876
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# 13 静态文件
STATIC_URL = '/static/'
# 14 表中,默认可以不写id,id主键自增,之前全是AutoField,长度很短
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
登录功能
表模型
from django.db import models
# Create your models here.
class UserInfo(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=64)
user_type = models.IntegerField(choices=((1, '超级管理员'), (2, '普通登录用户'), (3, '2B用户')), default=3)
class UserToken(models.Model):
token = models.CharField(max_length=64)
user = models.OneToOneField(to=UserInfo, on_delete=models.CASCADE)
视图类
import uuid
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from .models import *
class UserView(ViewSet):
authentication_classes = []
permission_classes = []
@action(methods=['POST'], detail=False)
def login(self, request):
username = request.headers.get('username')
password = request.headers.get('password')
user = UserInfo.objects.filter(name=username, password=password).first()
if user:
print('登陆成功')
token = str(uuid.uuid4())
UserToken.objects.update_or_create(user=user, defaults={'token': token})
return Response({'code': 200, 'msg': '登陆成功', 'token': token})
return Response({'code': 201, 'msg': '用户名或者密码错误'})
# 回顾
UserToken表中有user字段
拿到了一个UserToken表的对象
user_token.token 就是字符串
user_token.user 基于对象的跨表查询,拿到的是user对象 user_token.user.password
user_token.user_id 隐藏了这个字段,是可以用的,它是管理的user对象的id号
查询功能
UserToken.objects.filter(user=user对象)
UserToken.objects.filter(user_id=user.id)
路由
# 方式一:
path('login/', views.UserView.as_view({'post':'login'})),
# 路由如果这样写,是不需要使用action装饰器
# 方式二:自动生成路由---》视图类中一定要用action装饰器
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('user', views.UserView, 'user')
urlpatterns = [
path('admin/', admin.site.urls),
]
# http://127.0.0.1:8000/user/login/
urlpatterns += router.urls
认证组件
# APIView执行流程
-在视图视图类的方法之前,执行了三大认证
-认证
# 认证:登录认证
-登录认证---》控制,某个接口必须登录后才能访问
# 认证组件使用步骤(固定用法)
1 写一个类,继承BaseAuthentication
2 在类中写:authenticate
3 在方法中,完成登录认证,如果 不是登录的,抛异常
4 如果是登录的,返回登录用户和token
5 在视图类中,使用认证类(局部使用)
class BookView(APIView):
authentication_classes = [LoginAuth, ]
6 全局使用:
# 全局使用
### 重点:不要在配置文件中,导入莫名其妙的包
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'app01.auth.LoginAuth'
],
}
7 全局使用后,局部禁用
class UserView(ViewSet):
# 局部禁用
authentication_classes = []
8 认证类的使用顺序
-优先用视图类配置的
-其次用项目配置文件
-最后用drf默认的配置
# 小重点;一旦通过认证,在request中就有当前登录用户
def get(self, request):
# 一旦通过认证,在request中就有当前登录用户
print(request.user.name,'访问了接口')
权限组件
# 大家都登录了,但有的功能(接口),只有超级管理员能做,有的功能所有登录用户都能做----》这就涉及到权限的设计了
# 权限设计:比较复杂---》有acl,rbac,abac。。。
# 咱们现在只是为了先讲明白,drf的权限组件如何用,咱们先以最简单的为例
-查询所有图书:所有登录用户都能访问(普通用户和超级管理员)
-其实没有权限控制
-删除图书,只有超级管理员能访问
-给其它用户设置的权限
# 权限类的使用步骤
1 写一个类,继承BasePermission
2 在类中写方法:has_permission
-如果有权限,就返回True
-如果没有权限,就返回False
-错误信息是self.message='字符串'
3 局部使用
class BookDetailView(APIView):
permission_classes = [AdminPermission, ]
4 全局使用
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'app01.permission.AdminPermission'
],
}
5 局部禁用
class BookView(APIView):
permission_classes = []
频率组件
# 限制访问频次
-比如某个接口,一分钟只能访问5次,超过了就得等
-按IP地址 限制
-按用户id 限制
# 频率类的使用步骤
1 写个类,继承:SimpleRateThrottle
2 重写某个方法:get_cache_key
-可以返回ip或用户id
-返回什么,就以什么做频率限制
3 写一个类属性,随意命名一个名
scope = 'lqz'
4 在配置文件中配置:
'DEFAULT_THROTTLE_RATES': {
'lqz': '3/m' # 一分钟访问3次
},
5 全局用
'DEFAULT_THROTTLE_CLASSES': [
],
6 局部用
class BookView(APIView):
throttle_classes = [MyThrottle]
中间件执行ip限制
中间件类
import time
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin # 想自定义中间件类必须要继承这个玩意
time_dic = {}
class middleThrottle(MiddlewareMixin):
def process_request(self, request): # 提供了5个方法,这个是响应来的时候执行
ip = request.META.get('REMOTE_ADDR')
if ip in time_dic:
time_dic[ip].append(time.time())
else:
time_dic[ip] = [time.time()]
if len(time_dic[ip]) > 5:
time_d = time_dic[ip][5] - time_dic[ip][1]
time_dic[ip].pop(0)
print(time_d)
if time_d > 60:
return None
else:
return HttpResponse("访问频繁还要等待%s秒" % (60 - int(time_d)))
# 写完中间件后要在配置文件中注册
标签:django,token,user,time,contrib,import,认证,三大
From: https://www.cnblogs.com/juzixiong/p/17429536.html