干巴爹兔的博客 干巴爹兔的博客
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

干巴爹兔

卑微的前端打工人
首页
  • 前端文章

    • JavaScript
    • HTML
    • Vue
  • 学习笔记

    • JavaScript教程
    • React学习笔记
    • Electron学习笔记
  • 开源项目

    • cloud-app-admin
    • 下班了吗Vscode插件
    • Subversion变更单插件
  • Server

    • Django
  • 学习笔记

    • MySQL学习笔记
  • 运维

    • 服务器部署
    • Linux
  • 日常学习

    • 学习方法
关于
收藏
友链
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Django

    • Django框架初体验(一)
    • Django框架初体验(二)
    • Django框架初体验(三)
    • Django框架初体验(四)
    • 给django添加jwt授权
      • 安装
      • 使用
        • 创建token
        • 解析token
  • 学习笔记

  • 后端
  • Django
干巴爹兔
2020-04-12
目录

给django添加jwt授权

部分内容参考于jwt认证流程 (opens new window)

代码实现(持续更新中):Gitee (opens new window)

# 安装

首先安装pyjwt:

pip3 install pyjwt

# 使用

# 创建token

在根目录目录新建util文件夹,新建jwt_auth.py,代码如下:

import jwt
import datetime
from django.conf import settings
from jwt import exceptions

JWT_SALT = settings.SECRET_KEY

def create_token(payload, timeout=20):
    """
    :param payload:  例如:{'user_id':1,'username':'wupeiqi'}用户信息
    :param timeout: token的过期时间,默认20分钟
    :return:
    """
    headers = {
        'typ': 'jwt',
        'alg': 'HS256'
    }
    payload['exp'] = datetime.datetime.utcnow() + datetime.timedelta(minutes=timeout)
    result = jwt.encode(payload=payload, key=JWT_SALT, algorithm="HS256", headers=headers).decode('utf-8')
    return result


def parse_payload(token):
    """
    对token进行和发行校验并获取payload
    :param token:
    :return:
    """
    result = {'status': False, 'data': None, 'error': None}
    try:
        verified_payload = jwt.decode(token, JWT_SALT, True)
        result['status'] = True
        result['data'] = verified_payload
    except exceptions.ExpiredSignatureError:
        result['error'] = 'token已失效'
    except jwt.DecodeError:
        result['error'] = 'token认证失败'
    except jwt.InvalidTokenError:
        result['error'] = '非法的token'
    return result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

其中JWT_SALT是加密需要用到的盐,我这里取的是Django的默认的SECRET

在你的登录接口使用create_token方法:

# 登录获取token
@require_http_methods(["POST"])
@method_decorator(csrf_exempt, name='dispatch')
def login(request):
    response = {}
    try:
        data = json.loads(request.body)
        user = data.get('username')
        pwd = hashlib.sha1(data.get('password').encode('utf-8')).hexdigest()
        user_obj = Creater.objects.filter(name=user,password=pwd).first()
        if not user_obj:
            response['msg'] = '用户账户或密码错误'
            response['error_num'] = 1
            return JsonResponse(response)
        token = create_token({'username': user})
        user_obj.token = token
        user_obj.save()
        response['token'] = token
        response['msg'] = 'SUCCESS'
        response['error_num'] = 0          
    except Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1
    return JsonResponse(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

思路:显示从数据库中获取信息判断用户是否存在,如果存在,执行token = create_token({'username': user}),并将token存入数据库中

# 解析token

我们需要用到util中的另一个方法parse_payload,我打算用装饰器的方式写,这样可以区分一些路由需要权限与否,首先在根目录新建decorator文件夹,新建jwt.py,代码如下:

from django.conf import settings
from django.http import JsonResponse
from django.contrib.auth import get_user_model
from django.core.exceptions import PermissionDenied
from utils.jwt_auth import parse_payload
  
 
def auth_permission_required():
    def decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
                try:
                    authorization = request.META.get('HTTP_AUTHORIZATION', '')
                    auth = authorization.split()
                except AttributeError:
                    return JsonResponse({"code": 401, "message": "No authenticate header"})
 
                # 用户通过API获取数据验证流程
                if not auth:
                    return JsonResponse({'error': '未获取到Authorization请求头', 'status': False})
                if auth[0].lower() != 'bearer':
                    return JsonResponse({'error': 'Authorization请求头中认证方式错误', 'status': False})
                if len(auth) == 1:
                    return JsonResponse({'error': "非法Authorization请求头", 'status': False})
                elif len(auth) > 2:
                    return JsonResponse({'error': "非法Authorization请求头", 'status': False})
                token = auth[1]
                result = parse_payload(token)
                if not result['status']:
                    return JsonResponse(result)
 
                return view_func(request, *args, **kwargs)
 
        return _wrapped_view
 
    return decorator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

定义了装饰器就可以在view中引入它,在你需要权限验证的地方加上就可以了:

# 创建文章
@require_http_methods(["POST"])
@method_decorator(csrf_exempt, name='dispatch')
@auth_permission_required()
def create_article(request):
    response = {}
    try:
        data = json.loads(request.body)
        category = Category.objects.get(name=data.get('category'))
        name = Creater.objects.get(name=data.get('name'))
        article = Article()
        article.title = data.get('title')
        article.content = data.get('content')
        article.category = category
        article.name = name
        article.save()
        response['msg'] = 'success'
        response['error_num'] = 0
    except Exception as e:
        response['msg'] = str(e)
        response['error_num'] = 1

    return JsonResponse(response)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)
#Django
上次更新: 2022/08/26, 15:52:02
Django框架初体验(四)
《MySQL学习笔记》

← Django框架初体验(四) 《MySQL学习笔记》→

最近更新
01
使用Vscode开发一个小插件
10-21
02
Vscode插件配置项监听
10-18
03
使用has属性构造必填效果
10-14
更多文章>
Theme by Vdoing | Copyright © 2020-2023 互联网ICP备案: 闽ICP备18027236号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式