Django普通用户模型实现JWT认证

适用于django中不想用restframework-jwt的童鞋

项目依赖

python3.6*
Django 3.0.1
PyJWT 1.7.1
djangorestframework 3.11.0

项目结构和模型层

Django普通用户模型实现JWT认证_第1张图片
image.png

settings.py 配置文件

Django普通用户模型实现JWT认证_第2张图片
image.png
Django普通用户模型实现JWT认证_第3张图片
image.png
Django普通用户模型实现JWT认证_第4张图片
image.png

settings.py代码

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
from rest_framework.permissions import IsAuthenticated

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'b=35bd&e1t%-alhxsb+g1hgd43xixo^ngn(y7=eu3$mueqjl$$'

# 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',
    'user',
]

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'user.user_func.Authenticated', #必须有
    ),

}
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'jwt_test.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(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',
            ],
        },
    },
]

WSGI_APPLICATION = 'jwt_test.wsgi.application'

# Database
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'jwt',  # 数据库名字
        'USER': 'root',  # 账号
        'PASSWORD': '123456',  # 密码
        'HOST': '127.0.0.1',  # IP
        'PORT': '3306',  # 端口
    }
}

# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

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/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

views.py 视图文件

登录视图

Django普通用户模型实现JWT认证_第5张图片
image.png
Django普通用户模型实现JWT认证_第6张图片
image.png
Django普通用户模型实现JWT认证_第7张图片
image.png

views.py代码

from django.contrib.auth.hashers import check_password,make_password
from django.db.models import Q
from django.http import JsonResponse
from django.shortcuts import render
from rest_framework.views import APIView
from user.models import Users
from user.user_func import *


class Login(APIView):
    permission_classes = []  # 取消全局的token认证 不然无法访问登录页面
    def get(self,request):
        return render(request,'login.html')

    def post(self,request):
        req = request.POST
        data={'code':400}
        user = Users.objects.filter(Q(username=req.get('username'))|Q(mobile=req.get('username'))).first()
        if user:
            if check_password(req.get('password'),user.password):
                data['code']=200
                data['token']=create_token(user)
            else:
                data['error']='no user'
        else:
            data['error']=' no  username or password'
        return JsonResponse(data)


class Register(APIView):
    permission_classes = [] # 注册视图 同上
    def get(self,request):
        return render(request,'register.html')
    def post(self,request):
        req = request.POST
        data={'code':400}
        try:
            Users.objects.get(Q(username=req.get('username'))|Q(mobile=req.get('username'))|Q(username=req.get('username')))
            data['error']='用户名或手机号已经存在'
        except:
            user=Users(username=req.get('username'),password=make_password(req.get('password1')),mobile=req.get('mobile'))
            user.save()
            data['code']=200
            data['token'] = create_token(user)
        return JsonResponse(data)

class JWT_test(APIView):
    permission_classes =[Authenticated,] # 使用自定义类的校验方法
    def get(self,request):
        return JsonResponse({'code':200,'msg':'token校验成功,get请求'})
    def post(self,request):
        return JsonResponse({'CODE':200,'msg':'token校验成功,post请求'})

user_func.py 用户方法

Django普通用户模型实现JWT认证_第8张图片
image.png
Django普通用户模型实现JWT认证_第9张图片
image.png
Django普通用户模型实现JWT认证_第10张图片
image.png

user_func.py代码

import time
import jwt
from jwt_test import settings

class Authenticated(): # 无需继承其他认证类
    def has_permission(self, request,view): # 必须是这个名字,必须多带一个没用的view参数
        token = request.META.get('HTTP_TOKEN')
        if token:
            BOOLEAN=verify_token(token=token) # 验证成功返回Ture 失效及错误token 返回False
            return BOOLEAN
        else:
            BOOLEAN=False
            return BOOLEAN



def verify_token(token):
    try:
        jwt.decode(token, settings.SECRET_KEY , algorithms=['HS256'])
        return True
    except:
        # '签名已过期
        return False


def create_token(user):
    payload = {"exp": int(time.time()) + 10, "sub": user.id, "username": user.username, }
    token = jwt.encode(payload,settings.SECRET_KEY , algorithm='HS256').decode('utf8')
    return token

url.py 路由文件

Django普通用户模型实现JWT认证_第11张图片
image.png

模板文件 login.html

Django普通用户模型实现JWT认证_第12张图片
image.png

模板文件 register.html

Django普通用户模型实现JWT认证_第13张图片
image.png

项目运行起来后 浏览器访问127.0.0.1:8000/login/

Django普通用户模型实现JWT认证_第14张图片
image.png

项目运行起来后 浏览器访问127.0.0.1:8000/jwt/

Django普通用户模型实现JWT认证_第15张图片
image.png

注册一个 账号

Django普通用户模型实现JWT认证_第16张图片
image.png

注册完成拿到token

下载谷歌插件json handler 可以看到和我一样的json样式

image.png

复制token打开Postman

Django普通用户模型实现JWT认证_第17张图片
image.png
Django普通用户模型实现JWT认证_第18张图片
image.png

当token过期 或者 没有携带token 或者 携带更改过的token 访问需要认证后的页面时

Django普通用户模型实现JWT认证_第19张图片
image.png

你可能感兴趣的:(Django普通用户模型实现JWT认证)