博客五部曲之三 - 博客RESTful


3029 浏览 5 years, 2 months

32 Django Rest Framework JWT & Curl Tests

版权声明: 转载请注明出处 http://www.codingsoho.com/

Django Rest Framework JWT & Curl Tests

参考文档

这是一个专门为django-rest-framework设计的前端验证框架

首先安装

pip install djangorestframework-jwt

src/blog/settings.py

"DEFAULT_AUTHENTICATION_CLASSES": (
        #'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',     
    "DEFAULT_PERMISSION_CLASSES": (
        'rest_framework.permissions.IsAuthenticatedOrReadOnly',
        'rest_framework.permissions.IsAuthenticated',

我们来做一个测试

将IsAuthenticatedOrReadOnly'改为IsAuthenticated,不允许浏览

"DEFAULT_AUTHENTICATION_CLASSES": (
        #'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',     
    "DEFAULT_PERMISSION_CLASSES": (
        'rest_framework.permissions.IsAuthenticated',

去掉CommentsLisView的授权

class CommentListAPIView(ListAPIView):
    serializer_class = CommentListSerializer
    # permission_classes = [AllowAny]

再次访问 http://127.0.0.1:8000/api/comments/

HTTP 401 Unauthorized
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
WWW-Authenticate: JWT realm="api"

{
    "detail": "Authentication credentials were not provided."
}

可以看到授权模块用的是JWT

如果DEFAULT_AUTHENTICATION_CLASSES改回到SessionAuthentication',报错如下

HTTP 403 Forbidden
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Authentication credentials were not provided."
}

我们创建URL去处理token
src/blog/urls.py

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
     url(r'^api/auth/token/', obtain_jwt_token),

访问 http://127.0.0.1:8000/api/auth/token/

执行post abcd/abcd, 返回结果如下

HTTP 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc1MDMyN30.5wws5JaW4yBp8Iky5FTX6x91URZho-JQ750loqzTTrE"
}

可以用下面的命令行

curl -X POST -d "username=abcd&password=abcd" http://127.0.0.1:8000/api/auth/token/

返回

C:\Users\Administrator>curl -X POST  -d "username=abcd&password=abcd" [http://127.0.0.1](http://127.0.0.1):8000/api/auth/token/
{"token":" eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc1MTY1Mn0.BDMx3uMZFrYYCTWmQVxV3oGICu_XS3cDBl7cMQL0yT8"}

如果不添加token信息,浏览评论时,会跟前面一样返回错误"Authentication credentials were not provided."

C:\Users\Administrator> curl [http://127.0.0.1](http://127.0.0.1):8000/api/comments/
{"detail":"Authentication credentials were not provided."}

添加token信息的格式为 ·curl -H "Authorization: JWT <your_token>" [http://localhost:8000/protected-url/](http://localhost:8000/protected-url/)

本例生成如下

curl -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc1MTY1Mn0.BDMx3uMZFrYYCTWmQVxV3oGICu_XS3cDBl7cMQL0yT8" http://127.0.0.1:8000/api/comments/

返回结果

C:\Users\Administrator>curl -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc1MTY1Mn0.BDMx3uMZFrYYCTWmQVxV3oGICu_XS3cDBl7cMQL0yT8" http://127.0.0.1:8000/api/comments/

{"count":7,"next":"[http://127.0.0.1](http://127.0.0.1):8000/api/comments/?page=2","previous":null,"results":[{"url":"[http://127.0.0.1](http://127.0.0.1):8000/api/comments/53","id":53,"content":"reply ++","reply_count":
1},{"url":"[http://127.0.0.1](http://127.0.0.1):8000/api/comments/52","id":52,"content":"this is comment ++","reply_count":0},{"url":"[http://127.0.0.1](http://127.0.0.1):8000/api/comments/51","id":51,"content":"this is
comment","reply_count":3},{"url":"[http://127.0.0.1](http://127.0.0.1):8000/api/comments/48","id":48,"content":"comments 2 on test","reply_count":2}]}

再次执行,按理由可以返回实际结果,实际上没有,后面要查一下

curl http://127.0.0.1:8000/api/comments/

创建post,名字为curl
换了Header为”json”,
Token有有效期,超过时间了需要重新获取 {"detail":"Signature has expired."},可以通过下面配置延迟时间

import datetime
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
}

curl -X POST -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc5MzMyMn0.HQbC7mrsb20bRe-m00NdB-m-GZ1leFX1UGcWyjei18o" -H "Content-Type: application/json" -d '{"content":"abcd", "title":"curl","publish":"2018-01-01"}' http://127.0.0.1:8000/api/posts/create

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "url": "[http://127.0.0.1](http://127.0.0.1):8000/api/posts/curl/",
    "title": "curl",
    "slug": "curl",
    "publish": "2018-01-01",
    "user": {
        "username": "abcd",
        "email": "abcd@abc.com",
        "first_name": "",
        "last_name": ""
    },
    "image": null,
    "content": "abcd",
    "html": "<p>abcd</p>\n",
    "comments": []
}

给这个post创建comments

curl -X POST -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc5MzMyMn0.HQbC7mrsb20bRe-m00NdB-m-GZ1leFX1UGcWyjei18o" -H "Content-Type: application/json" -d '{"content":"abcd"}' "http://127.0.0.1:8000/api/comments/create/?slug=curl&type=post"

注意:网址用双引号括起来,不加或用单引号会报错 {"non_field_errors":["This is not a valid content type"]}系统找不到指定的文件。

返回结果

{"id":61,"content":"abcd","timestamp":"2018-07-28T15:14:32.726000Z"}

查看这个comments http://127.0.0.1:8000/api/comments/61

HTTP 200 OK
Allow: GET, PUT, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 61,
    "user": {
        "username": "abcd",
        "email": "abcd@abc.com",
        "first_name": "",
        "last_name": ""
    },
    "content": "abcd",
    "reply_count": 0,
    "replies": [],
    "timestamp": "2018-07-28T15:14:32.726000Z",
    "content_object_url": "/api/posts/curl/"
}

添加子评论

curl -X POST -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFiY2QiLCJ1c2VyX2lkIjo3LCJlbWFpbCI6ImFiY2RAYWJjLmNvbSIsImV4cCI6MTUzMjc5MzMyMn0.HQbC7mrsb20bRe-m00NdB-m-GZ1leFX1UGcWyjei18o" -H "Content-Type: application/json" -d '{"content":"reply of abcd"}' http://127.0.0.1:8000/api/comments/create/?slug=curl&type=post&parent_id=61

返回结果

{"id":62,"content":"reply of abcd","timestamp":"2018-07-28T15:19:24.935000Z"}

刷新http://127.0.0.1:8000/api/comments/61,下面新添加了子评论

HTTP 200 OK
Allow: GET, PUT, DELETE, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 61,
    "user": {
        "username": "abcd",
        "email": "abcd@abc.com",
        "first_name": "",
        "last_name": ""
    },
    "content": "abcd",
    "reply_count": 1,
    "replies": [
        {
            "id": 62,
            "user": {
                "username": "abcd",
                "email": "abcd@abc.com",
                "first_name": "",
                "last_name": ""
            },
            "content": "reply of abcd",
            "timestamp": "2018-07-28T15:19:24.935000Z"
        }
    ],
    "timestamp": "2018-07-28T15:14:32.726000Z",
    "content_object_url": "/api/posts/curl/"
}

练习记录.....

'''
 curl -X POST -d "username=cfe&password=learncode" [http://127.0.0.1](http://127.0.0.1):8000/api/auth/token/

 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNmZSIsInVzZXJfaWQiOjEsImVtYWlsIjoiIiwiZXhwIjoxNDYxOTY1ODI5fQ.OTX7CZFZqxhaUnU9Da13Ebh9FY_bHMeCF1ypr9hXjWw

 curl -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNmZSIsInVzZXJfaWQiOjEsImVtYWlsIjoiIiwiZXhwIjoxNDYxOTY1ODI5fQ.OTX7CZFZqxhaUnU9Da13Ebh9FY_bHMeCF1ypr9hXjWw
 " [http://127.0.0.1](http://127.0.0.1):8000/api/comments/

 curl -X POST -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNmZSIsInVzZXJfaWQiOjEsImVtYWlsIjoiIiwiZXhwIjoxNDYxOTY2MTc4fQ._i5wEqJ_OO8wNiVVNAWNPGjGaO7OzChY0UzONgw06D0" -H "Content-Type: application/json" -d '{"content":"some reply to another try"}' '[http://127.0.0.1](http://127.0.0.1):8000/api/comments/create/?slug=new-title&type=post&parent_id=13'

 curl [http://127.0.0.1](http://127.0.0.1):8000/api/comments/
 '''

参考文档
https://earthchen.cn/2017/06/15/django_rest_framework_jwt/

src/blog/curl_tests.py

'''
curl -X POST -d "username=cfe&password=learncode" [http://127.0.0.1](http://127.0.0.1):8000/api/auth/token/

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNmZSIsInVzZXJfaWQiOjEsImVtYWlsIjoiIiwiZXhwIjoxNDYxOTY1ODI5fQ.OTX7CZFZqxhaUnU9Da13Ebh9FY_bHMeCF1ypr9hXjWw

curl -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNmZSIsInVzZXJfaWQiOjEsImVtYWlsIjoiIiwiZXhwIjoxNDYxOTY1ODI5fQ.OTX7CZFZqxhaUnU9Da13Ebh9FY_bHMeCF1ypr9hXjWw
" [http://127.0.0.1](http://127.0.0.1):8000/api/comments/


curl -X POST -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNmZSIsInVzZXJfaWQiOjEsImVtYWlsIjoiIiwiZXhwIjoxNDYxOTY2MTc4fQ._i5wEqJ_OO8wNiVVNAWNPGjGaO7OzChY0UzONgw06D0" -H "Content-Type: application/json" -d '{"content":"some reply to another try"}' '[http://127.0.0.1](http://127.0.0.1):8000/api/comments/create/?slug=new-title&type=post&parent_id=13'

curl [http://127.0.0.1](http://127.0.0.1):8000/api/comments/

curl -X POST -d "username=anotheruser123&password=anotheruser123" [http://127.0.0.1](http://127.0.0.1):8000/api/auth/token/

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFub3RoZXJ1c2VyMTIzIiwidXNlcl9pZCI6NywiZW1haWwiOiJhbm90aGVydXNlcjEyM0BnbWFpbC5jb20iLCJleHAiOjE0NjE5NjY0ODF9.KZ991-PGIm63BKikMbDSdFStStJ6uu6WtsraAmbo7BQ

curl -X POST -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFub3RoZXJ1c2VyMTIzIiwidXNlcl9pZCI6NywiZW1haWwiOiJhbm90aGVydXNlcjEyM0BnbWFpbC5jb20iLCJleHAiOjE0NjE5NjY0ODF9.KZ991-PGIm63BKikMbDSdFStStJ6uu6WtsraAmbo7BQ" -H "Content-Type: application/json" -d '{"content":"my new reply to another try"}' '[http://127.0.0.1](http://127.0.0.1):8000/api/comments/create/?slug=new-title&type=post&parent_id=13'
'''