Django建站历程:(二一)jwt为API添加身份认证

2019年8月31日 Jerry 4908 2021年1月17日

       之前在建站历程十八中写了django如何使用restframework编写自己所用的api,这篇接上篇说一下如何使用jwt进行api的身份验证。

前言

       JWT 就是 json web token 的缩写,token的作用很简单,一般用于识别用户身份,避免每次请求都需要验证。我们为什么需要认证呢?看下面这个例子:

       将django项目(地址:github)本地运行起来,之前我们都已经实现了api接口,于是输入以下地址(http://127.0.0.1:8000/api/laji/)可以获取到如下的信息:

       无需任何认证就可以得到我们想要的信息,如果用python脚本的话,代码如下:

# coding: UTF-8
import re
import requests

def get_url():
    url = "http://127.0.0.1:8000/api/laji/"
    r = requests.get(url)
    r.encoding = 'utf-8'
    print(r.text)

get_url()

       简单几句就能调用api获取到信息,但是这样会有些问题:

  • 所有人无需验证即可调用api,对于我们垃圾服务器来说是一种负担。
  • 对于post/put操作所有人都可以添加修改我们的内容,这是不安全的。

       于是,我们可以对api做一个验证,避免上述的问题。接下来说下 jwt 在django项目中的配置使用。

一、jwt的下载安装

       需要安装两个插件 djangorestframework-jwt 和 django-cors-headers,其中 django-cors-headers 用于解决所谓的跨域问题。

pip install djangorestframework-jwt
pip install django-cors-headers

       在全局settings.py install-app 中添加两个插件:

INSTALLED_APPS = [
    ...
    'rest_framework',
    'rest_framework.authtoken',  # 设置token
    'corsheaders',
    ...
]

      同样在 settings.py 中 middleware 中添加

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',   # 跨域
    ...
]

       同样在 settings.py 中 添加如下配置,表示认证进行jwt认证:

REST_FRAMEWORK = {
    .....
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    .....
}

二、添加url路由

       在全局路由url.py中添加如下,将 jwt 所需的url添加进去:

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    ....
    path('api-auth/', obtain_jwt_token),
    .......

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

三、修改处理函数

       需要在api处理函数(view.py)中添加认证代码,例如我们在所有垃圾查询函数中添加:

from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.authentication import SessionAuthentication


# 所有垃圾获取处理 继承listAPIView
class RubbishView(ListAPIView):
    # 认证后才可以往下进行
    permission_classes = (permissions.IsAuthenticated,)
    # 进行jwt验证
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

    queryset = Rubbish.objects.all()
    serializer_class = RubbishSerializer

       此时,我们再调用之前的api链接,提示应该如下,因为我们添加了需要认证验证:

四、jwt身份验证

       上述操作进行后,我们只有验证后才能调用api了,如何进行验证呢?

       其实也很简单,需要将用户名密码post给服务器,获取到服务器返回的token,我们接下来的put/get/post等操作将token填写到头中即可。说起来可能有点抽象,看下面这个例子:

       1、获取token

       以python为例,只需要向 "http://127.0.0.1:8000/api-auth/" 这个链接 post 我们的用户名密码(这个项目管理员用户名密码是 jerrycoding/jerry123 ), 即可获取到token:

def get_token():
    url = "http://127.0.0.1:8000/api-auth/"
    params = {"username": "jerrycoding", "password": "jerry123"}
    r = requests.post(url, data=params)
    r.encoding = 'utf-8'
    print(r.text)

       2、封装头进行数据获取

       这里要注意的是token头的封装,格式要注意!格式应该为“JWT +'token'”,JWT后面有一个空格,空格后就是获取到的token值。一个完整的例子代码如下:

# coding: UTF-8
import requests

def get_token():
    url = "http://127.0.0.1:8000/api-auth/"
    params = {"username": "jerrycoding", "password": "jerry123"}
    r = requests.post(url, data=params)
    r.encoding = 'utf-8'
    return r.json()["token"]


def get_url():
    # 获取token
    token = get_token()
    # 造头 注意格式
    headers = {'Authorization': 'JWT '+token}

    url = "http://127.0.0.1:8000/api/laji/"
    r = requests.get(url, headers=headers)
    r.encoding = 'utf-8'
    print(r.text)

get_url()

       此时,运行代码我们又能获取数据了,而且数据获取是需要认证才可以的。

       以上就是如何简单的为 api 添加身份验证,上述只是允许登陆用户调用api,比如你有时候只要管理员来调用api或者指定某个用户调用api,直接改处理函数中的认证方式就可以,大家自己可以再深入研究下。最后,本期修改代码已经上传工程代码目录 github


《django 建站历程系列文章》

(一)服务器的选取与环境准备

(二)创建第一个project和app

(三)创建并显示博客的主页导航栏

(四)django-allauth实现用户登陆

(五)django-allauth实现第三方登陆

(六)使用bootstrap3美化登陆界面

(七)添加用户签名字段

(八)自定义用户头像

(九)发布我的第一篇博客

(十)CKEditor的配置使用

(十一)ajax实现文章添加评论

(十二)signal自动消息通知

(十三)基于django-haystack的全文搜索

(十四)配置SSL证书实现网站HTTPS访问

(十五)免费开启七牛云CDN加速

(十六)particles 粒子背景插件

(十七)集成 xadmin2 后台管理

(十八)RestFramework 编写API

(十九)Nginx+uwsgi 部署 django

(二十)自定义网站404界面

(二一)jwt为API添加身份认证

jerrycoding 博客源码大公开


原创文章,转载请注明出处: https://jerrycoding.com/article/site_building_21

微信
jerry微信赞助
支付宝
jerry支付宝赞助

您尚未登录,暂时无法评论。请先 登录 或者 注册

0 人参与 | 0 条评论