JWT配置与使用[Python基础]
1.jwt的安装配置 .
1.1安装JWT
pip install djangorestframework-jwt==1.11.0
1.2
# jwt载荷中的有效期设置JWT_AUTH = {
# 1.token前缀:headers中 Authorization 值的前缀
"JWT_AUTH_HEADER_PREFIX": "JWT",
# 2.token有效期:一天有效
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=1),
# 3.刷新token:允许使用旧的token换新token,接口对接需要设置为true
"JWT_ALLOW_REFRESH": True,
# 4.token有效期:token在24小时内过期, 可续期token
"JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(hours=24),
# 5.自定义JWT载荷信息:自定义返回格式,需要手工创建
"JWT_RESPONSE_PAYLOAD_HANDLER": "user.utils.jwt_response_payload_handler",
}
"""Django settings for opwf project.
Generated by "django-admin startproject" using Django 2.0.13.
For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""import datetime
import os, sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, "apps"))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "uorj1ni^mnut@wo@c%)iv)%5=8dxlml4-j0!f3b%4#f*8a5)3t"
# SECURITY WARNING: don"t run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"corsheaders",
"user.apps.UserConfig",
"workflow.apps.WorkflowConfig",
"workerorder.apps.WorkerorderConfig",
# "jwt",
# "rest_framework_jwt",
# "rest_framework.authentication"
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"corsheaders.middleware.CorsMiddleware",
# "django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "opwf.urls"
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
"http://127.0.0.1:8080",
"http://localhost:8080",
)
CORS_ALLOW_CREDENTIALS = True
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"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",
],
},
},
]
WSGI_APPLICATION = "opwf.wsgi.application"
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "opwf_db",
"USER": "root",
"PASSWORD": "1",
"HOST": "127.0.0.1",
"PORT": "3306"
}
}
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
REST_FRAMEWORK = {
# 文档报错: AttributeError: ‘AutoSchema’ object has no attribute ‘get_link’
# 用下面的设置可以解决
"DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.AutoSchema",
# 默认设置是:
# "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.openapi.AutoSchema",
# 异常处理器
# "EXCEPTION_HANDLER": "user.utils.exception_handler",
# Base API policies 默认渲染器类
"DEFAULT_RENDERER_CLASSES": [
"rest_framework.renderers.JSONRenderer",
"rest_framework.renderers.BrowsableAPIRenderer",
],
# 默认解析器类
"DEFAULT_PARSER_CLASSES": [
"rest_framework.parsers.JSONParser",
"rest_framework.parsers.FormParser",
"rest_framework.parsers.MultiPartParser"
],
# 1.认证器(全局)
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_jwt.authentication.JSONWebTokenAuthentication", # 在 DRF中配置JWT认证
# "rest_framework.authentication.SessionAuthentication", # 使用session时的认证器
# "rest_framework.authentication.BasicAuthentication" # 提交表单时的认证器
],
# 2.权限配置(全局): 顺序靠上的严格
"DEFAULT_PERMISSION_CLASSES": [
# "rest_framework.permissions.IsAdminUser", # 管理员可以访问
# "rest_framework.permissions.IsAuthenticated", # 认证用户可以访问
# "rest_framework.permissions.IsAuthenticatedOrReadOnly", # 认证用户可以访问, 否则只能读取
# "rest_framework.permissions.AllowAny", # 所有用户都可以访问
# "user.utils.VipPermission", #自定义权限
],
# 3.限流(防爬虫)
"DEFAULT_THROTTLE_CLASSES": [
"rest_framework.throttling.AnonRateThrottle",
"rest_framework.throttling.UserRateThrottle",
],
# 3.1限流策略
# "DEFAULT_THROTTLE_RATES": {
# "user": "100/hour", # 认证用户每小时100次
# "anon": "300/day", # 未认证用户每天能访问3次
# },
"DEFAULT_CONTENT_NEGOTIATION_CLASS": "rest_framework.negotiation.DefaultContentNegotiation",
"DEFAULT_METADATA_CLASS": "rest_framework.metadata.SimpleMetadata",
"DEFAULT_VERSIONING_CLASS": None,
# 4.分页(全局):全局分页器, 例如 省市区的数据自定义分页器, 不需要分页
# "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
# # 每页返回数量
# "PAGE_SIZE": 3,
# 5.过滤器后端
"DEFAULT_FILTER_BACKENDS": [
"django_filters.rest_framework.DjangoFilterBackend",
# "django_filters.rest_framework.backends.DjangoFilterBackend", 包路径有变化
],
# 5.1过滤排序(全局):Filtering 过滤排序
"SEARCH_PARAM": "search",
"ORDERING_PARAM": "ordering",
"NUM_PROXIES": None,
# 6.版本控制:Versioning 接口版本控制
"DEFAULT_VERSION": None,
"ALLOWED_VERSIONS": None,
"VERSION_PARAM": "version",
# Authentication 认证
# 未认证用户使用的用户类型
"UNAUTHENTICATED_USER": "django.contrib.auth.models.AnonymousUser",
# 未认证用户使用的Token值
"UNAUTHENTICATED_TOKEN": None,
# View configuration
"VIEW_NAME_FUNCTION": "rest_framework.views.get_view_name",
"VIEW_DESCRIPTION_FUNCTION": "rest_framework.views.get_view_description",
"NON_FIELD_ERRORS_KEY": "non_field_errors",
# Testing
"TEST_REQUEST_RENDERER_CLASSES": [
"rest_framework.renderers.MultiPartRenderer",
"rest_framework.renderers.JSONRenderer"
],
"TEST_REQUEST_DEFAULT_FORMAT": "multipart",
# Hyperlink settings
"URL_FORMAT_OVERRIDE": "format",
"FORMAT_SUFFIX_KWARG": "format",
"URL_FIELD_NAME": "url",
# Encoding
"UNICODE_JSON": True,
"COMPACT_JSON": True,
"STRICT_JSON": True,
"COERCE_DECIMAL_TO_STRING": True,
"UPLOADED_FILES_USE_URL": True,
# Browseable API
"HTML_SELECT_CUTOFF": 1000,
"HTML_SELECT_CUTOFF_TEXT": "More than {count} items...",
# Schemas
"SCHEMA_COERCE_PATH_PK": True,
"SCHEMA_COERCE_METHOD_NAMES": {
"retrieve": "read",
"destroy": "delete"
},
# "Access-Control-Allow-Origin":"http://localhost:8080",
# "Access-Control-Allow-Credentials": True
}
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",
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
LANGUAGE_CODE = "zh-hans"
TIME_ZONE = "Asia/Shanghai"
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = "/static/"
AUTH_USER_MODEL = "user.User"
# jwt载荷中的有效期设置
JWT_AUTH = {
# 1.token前缀:headers中 Authorization 值的前缀
"JWT_AUTH_HEADER_PREFIX": "JWT",
# 2.token有效期:一天有效
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=1),
# 3.刷新token:允许使用旧的token换新token
"JWT_ALLOW_REFRESH": True,
# 4.token有效期:token在24小时内过期, 可续期token
"JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(hours=24),
# 5.自定义JWT载荷信息:自定义返回格式,需要手工创建
"JWT_RESPONSE_PAYLOAD_HANDLER": "user.utils.jwt_response_payload_handler",
}
settings.py
from django.urls import include, pathfrom rest_framework.authtoken.views import obtain_auth_tokenfrom user import viewsfrom rest_framework.routers import SimpleRouter, DefaultRouterfrom rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token# 自动生成路由方法, 必须使用视图集#
router = SimpleRouter() # 没有根路由 /user/ 无法识别router = DefaultRouter() # 有根路由
router.register(r"user", views.UserViewSet)
urlpatterns = [
path("index/", views.index), # 函数视图
path("login/", obtain_jwt_token), # 获取token,登录视图
path("register/",views.Register.as_view()), #注册用户
path("refresh/", refresh_jwt_token), # 刷新token
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")), # 认证地址
]
urlpatterns += router.urls # 模块地址
# print(router.urls)
# obtain_jwt_token = ObtainJSONWebToken.as_view() # 获取token
# refresh_jwt_token = RefreshJSONWebToken.as_view() # 刷新token
# verify_jwt_token = VerifyJSONWebToken.as_view() # 修改token
def jwt_response_payload_handler(token, user=None, request=None, role=None):"""自定义jwt认证成功返回数据
:token 返回的jwt
:user 当前登录的用户信息[对象]
:request 当前本次客户端提交过来的数据
:role 角色
"""if user.first_name:
name = user.first_name
else:
name = user.username
return {
"authenticated": "true",
"id": user.id,
"role": role,
"name": name,
"username": user.username,
"email": user.email,
"token": token,
}
1.6 user/utils.py 生成token
#生成jwt_tokendef create_token(user): #user:接收的用户对象
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
return token
2.代码实践 .
from django.db import models# Create your models here.from django.contrib.auth.models import AbstractUser
class Vip(models.Model):
vip_choices = (
("1","普通会员"),
("2","高级会员")
)
vip_name = models.CharField(verbose_name="vip名称",max_length=20)
vip_type = models.CharField(verbose_name="vip种类",max_length=20,choices=vip_choices)
desc = models.CharField(verbose_name="vip描述",max_length=255)
class Meta:
db_table = "tb_vip"
verbose_name = "Vip表"
class User(AbstractUser):
nike_name = models.CharField(verbose_name="昵称",max_length=30,null=True)
phone = models.CharField(verbose_name="手机号",max_length=30,null=True)
email = models.CharField(verbose_name="邮箱",max_length=255,null=True)
address = models.CharField(verbose_name="地址",max_length=255,null=True)
vip = models.ForeignKey(Vip,on_delete=models.CASCADE,null=True,default=None)
class Meta:
db_table = "tb_user"
verbose_name = "用户表"
user/models.py
from django.urls import pathfrom . import viewsfrom rest_framework_jwt.views import obtain_jwt_tokenurlpatterns
= [path(
"register/",views.Register.as_view()), #注册path("login/",obtain_jwt_token), #登录
path("test/",views.Test.as_view()), #测试权限用的
]
user/urls.py
from django.shortcuts import render# Create your views here.from rest_framework.views import APIView,Response
from .serializers import *
from .models import *
from user.utils import create_token
from rest_framework.permissions import IsAuthenticated,IsAdminUser,AllowAny
from user.utils import VipPermission
class Register(APIView):
def post(self,requset):
print(requset.data)
username = requset.data.get("username")
password = requset.data.get("password")
phone = requset.data.get("phone")
email = requset.data.get("email")
address = requset.data.get("address")
ifnot all([username,password,phone,email,address]):
return Response({"msg":"数据不完整","code":400})
#create添加
# user_obj = User.objects.create(username=username,password=make_password(password),
# phone=phone,email=email,address=address)
#
# token = create_token(user_obj)
#
# data = {
# "id":user_obj.pk,
# "username":user_obj.username,
# "phone":user_obj.phone,
# "email":user_obj.email,
# "address":user_obj.address,
# "token":token
# }
#序列化添加
user_serializer = UserSerializers(data=requset.data)
user_serializer.is_valid()
user_serializer.save()
return Response({"msg":"注册成功","code":200,"data":user_serializer.data})
class Test(APIView):
# permission_classes = (IsAuthenticated,) #只有认证用户可以访问
# permission_classes = (IsAdminUser,) #只有管理员用户可以访问
以上是 JWT配置与使用[Python基础] 的全部内容, 来源链接: utcz.com/z/530642.html