JWT认证的REST框架

原文链接

概述

这个包提供对Django REST frameworkJSON Web Token 认证支持。

需要满足条件

  • Python (2.7, 3.3, 3.4, 3.5)
  • Django (1.8, 1.9, 1.10)
  • Django REST Framework (3.0, 3.1, 3.2, 3.3, 3.4, 3.5)

安全

与JWT的一些更典型的用法不同,此模块仅生成身份验证令牌,该身份验证令牌将验证请求DRF保护的API资源之一的用户。实际的请求参数本身不包含在JWT声明中,这意味着它们没有被签名并且可能被篡改。 您仅应通过SSL / TLS公开API端点,以防止内容篡改和某些类型的重放攻击。

安装

使用pip方式安装

$ pip install djangorestframework-jwt

用法

settings.py中,添加JSONWebTokenAuthentication到Django rest framework的DEFAULT_AUTHENTICATION_CLASSES中。

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}

urls.py中,添加以下URL路由,以允许通过包含用户名和密码的POST获得令牌。

from rest_framework_jwt.views import obtain_jwt_token
#... urlpatterns = [
'',
# ... url(r'^api-token-auth/', obtain_jwt_token),
]

如果您拥有一个用户名为admin和密码为password123的用户,则可以通过在终端中执行以下操作来简单测试端点是否正常运行。

$ curl -X POST -d "username=admin&password=password123" http://localhost:8000/api-token-auth/

或者,您可以使用Django REST框架支持的所有内容类型来获取auth令牌。 例如:

$ curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"password123"}' http://localhost:8000/api-token-auth/

您是不是要找: [Now in order to access protected api urls you must include the Authorization: JWT <your token> header.](javascript:void(0))

现在,为了访问受保护的api网址,您必须包含Authorization:JWT <your_token>标头。

$ curl -H "Authorization: JWT <your_token>" http://localhost:8000/protected-url/

刷新令牌

如果JWT_ALLOW_REFRESH为True,则可以“刷新”未过期的令牌以获得具有更新的过期时间的全新令牌。 添加如下网址格式:

from rest_framework_jwt.views import refresh_jwt_token
# ... urlpatterns = [
# ...
url(r'^api-token-refresh/', refresh_jwt_token),
]

如下所示将现有令牌传递到刷新端点:{“ token”:EXISTING_TOKEN}。 请注意,只有未过期的令牌才有效。 JSON响应看起来与正常的获取令牌端点{“ token”:NEW_TOKEN}相同。

$ curl -X POST -H "Content-Type: application/json" -d '{"token":"<EXISTING_TOKEN>"}' http://localhost:8000/api-token-refresh/

可以重复使用令牌刷新(令牌1->令牌2->令牌3),但是此令牌链将原始令牌(使用用户名/密码凭证获取)的时间存储为orig_iat。 您最多只能将令牌刷新到JWT_REFRESH_EXPIRATION_DELTA

一个典型的用例是一个Web应用程序,您想让用户“登录”该网站而不必重新输入密码,或者在令牌过期之前被吓倒了。 想象一下,他们有一个1个小时的令牌,正好在他们仍在做某事的最后一刻。 使用移动设备,您也许可以存储用户名/密码来获取新令牌,但这在浏览器中并不是一个好主意。 每次用户加载页面时,您都可以检查是否存在现有的未过期令牌,如果该令牌即将过期,请刷新该令牌以扩展会话。 换句话说,如果用户正在活跃地使用您的网站,则他们可以保持其“会话(session)”有效。

验证令牌

在某些微服务架构中,身份验证由单个服务处理。 其他服务委托确认用户已登录到此身份验证服务的责任。 这通常意味着服务会将将从用户收到的JWT传递给身份验证服务,并在将受保护资源返回给用户之前等待JWT有效的确认。

此软件包使用验证端点支持此设置。 添加以下网址格式:

from rest_framework_jwt.views import verify_jwt_token

#...

urlpatterns = [
# ...
url(r'^api-token-verify/', verify_jwt_token),
]

将令牌传递到验证端点将返回200响应,如果令牌有效,则返回令牌。 否则,它将返回一个400 Bad Request(错误请求)以及一个指出令牌无效的原因的错误。

$ curl -X POST -H "Content-Type: application/json" -d '{"token":"<EXISTING_TOKEN>"}' http://localhost:8000/api-token-verify/

其它配置

JWT_AUTH = {
'JWT_ENCODE_HANDLER':
'rest_framework_jwt.utils.jwt_encode_handler', 'JWT_DECODE_HANDLER':
'rest_framework_jwt.utils.jwt_decode_handler', 'JWT_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_payload_handler', 'JWT_PAYLOAD_GET_USER_ID_HANDLER':
'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler', 'JWT_RESPONSE_PAYLOAD_HANDLER':
'rest_framework_jwt.utils.jwt_response_payload_handler', 'JWT_SECRET_KEY': settings.SECRET_KEY,
'JWT_GET_USER_SECRET_KEY': None,
'JWT_PUBLIC_KEY': None,
'JWT_PRIVATE_KEY': None,
'JWT_ALGORITHM': 'HS256',
'JWT_VERIFY': True,
'JWT_VERIFY_EXPIRATION': True,
'JWT_LEEWAY': 0,
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
'JWT_AUDIENCE': None,
'JWT_ISSUER': None, 'JWT_ALLOW_REFRESH': False,
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7), 'JWT_AUTH_HEADER_PREFIX': 'JWT',
'JWT_AUTH_COOKIE': None, }

该软件包使用JSON Web令牌Python实现PyJWT,并允许修改其中的一些可用选项。

JWT_SECRET_KEY

这是用于签署JWT的密钥。确保这是安全的,并且不会共享或公开。

默认值为项目的settings.SECRET_KEY

JWT_GET_USER_SECRET_KEY

这是JWT_SECRET_KEY的更强大的版本。它是按用户定义的,因此,如果令牌被盗用,所有者可以轻松更改它。更改此值将使给定用户的所有令牌不可用。值应该是一个函数,仅接受用户作为参数并返回它的密钥。

默认为None

JWT_PUBLIC_KEY

这是cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey类型的对象。它将用于验证传入的JWT的签名。设置后将覆盖JWT_SECRET_KEY阅读文档以获取更多详细信息。请注意,必须将JWT_ALGORITHM设置为RS256RS384RS512之一。

默认为None

JWT_PRIVATE_KEY

这是cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey类型的对象。它将用于对JWT的签名组件进行签名。设置后将覆盖JWT_SECRET_KEY阅读文档以获取更多详细信息。请注意,必须将JWT_ALGORITHM设置为RS256RS384RS512之一。

默认为None

JWT_ALGORITHM

可能的值是PyJWT中任何受支持的密码签名算法

默认值为“ HS256”

JWT_VERIFY

如果密码错误,则会引发一个jwt.DecodeError告诉您。您仍然可以通过将JWT_VERIFY设置为False来获得有效负载。

默认值为True

JWT_VERIFY_EXPIRATION

您可以通过将JWT_VERIFY_EXPIRATION设置为False来关闭到期时间验证。如果没有到期验证,JWT将永远存在,这意味着攻击者可以无限期地使用泄露的令牌。

默认值为True

JWT_LEEWAY

这使您可以验证过去但不是很远的到期时间。例如,如果您有一个JWT有效负载,其有效时间设置为创建后的30秒,但您知道有时您将在30秒后对其进行处理,则可以将回旋时间设置为10秒,以便有一定的余量。

默认值为0秒。

JWT_EXPIRATION_DELTA

这是Python的datetime.timedelta的一个实例。这将被添加到datetime.utcnow()来设置到期时间。

默认值为datetime.timedelta(seconds = 300)(5分钟)

JWT_AUDIENCE

这是一个字符串,将根据令牌的aud字段(如果存在)进行检查。

默认值为None(如果JWT上出现aud,则失败)。

JWT_ISSUER

这是一个字符串,将根据令牌的iss字段进行检查。

默认值为None(不检查JWT上的iss)。

JWT_ALLOW_REFRESH

启用令牌刷新功能。从rest_framework_jwt.views.obtain_jwt_token发行的令牌将具有orig_iat字段。默认为False

JWT_REFRESH_EXPIRATION_DELTA

令牌刷新的限制是一个datetime.timedelta实例。这是原始令牌之后可以刷新未来令牌的时间。

默认值为datetime.timedelta(days = 7)(7天)

JWT_PAYLOAD_HANDLER

指定自定义函数以生成令牌有效载荷。

JWT_PAYLOAD_GET_USER_ID_HANDLER

如果您存储的user_id与默认的有效负载处理程序不同,请实现此功能以从有效负载中获取user_id。注意:不推荐使用JWT_PAYLOAD_GET_USERNAME_HANDLER

JWT_PAYLOAD_GET_USERNAME_HANDLER

如果您存储的username与默认有效负载处理程序不同,请实施此功能以从有效负载中获取用户名。

JWT_RESPONSE_PAYLOAD_HANDLER

负责控制登录或刷新后返回的响应数据。重写以返回自定义响应,例如包括用户的序列化表示形式。默认返回JWT令牌。

def jwt_response_payload_handler(token, user=None, request=None):
return {
'token': token,
'user': UserSerializer(user, context={'request': request}).data
}

默认是 {'token': token}

JWT_AUTH_HEADER_PREFIX

您可以修改需要与令牌一起发送的Authorization标头值前缀。 默认值为JWT。 PR#4中引入了此决定,以允许在DRF中同时使用此程序包和OAuth2。

用于令牌和授权标头的另一个常见值是Bearer

默认值为JWT

JWT_AUTH_COOKIE

如果除了授权标头之外还想使用http cookie作为令牌的有效传输方式,则可以将其设置为字符串。 您在此处设置的字符串将用作在请求令牌时将在响应标头中设置的cookie名称。 令牌验证过程还将调查此cookie(如果已设置)。 如果请求中同时包含标头和cookie,则“授权”标头具有优先权。

默认值为“None”,创建令牌时不设置cookie,或在验证令牌时不接受。

扩展JSONWebTokenAuthentication

现在,JSONWebTokenAuthentication假定JWT将出现在标头或cookie(如果已配置)中(请参阅JWT_AUTH_COOKIE)。 JWT规范不需要这样做(请参阅:进行服务调用)。 例如,JWT可以出现在查询字符串中。 如果用户无法设置标头(例如HTML中的src元素),则需要具有在查询字符串中发送JWT的功能。

为了实现此功能,用户可以编写自定义身份验证

class JSONWebTokenAuthenticationQS(BaseJSONWebTokenAuthentication):
def get_jwt_value(self, request):
return request.QUERY_PARAMS.get('jwt')

建议使用BaseJSONWebTokenAuthentication,这是一个新的基类,没有解析HTTP标头的逻辑。

手动创建新令牌

有时您可能需要手动生成令牌,例如在创建帐户后立即将令牌返回给用户。 您可以按照以下步骤进行操作:

from rest_framework_jwt.settings import api_settings

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)

【翻译】REST framework JWT Auth(django rest framework-jwt)的更多相关文章

  1. 6 Django REST framework JWT 和登录功能实现

    JWT 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证. 我们不再使用Session认证机制,而使用Json Web Token认证机制. Json web token ( ...

  2. 用Django Rest Framework和AngularJS开始你的项目

    Reference: http://blog.csdn.net/seele52/article/details/14105445 译序:虽然本文号称是"hello world式的教程&quo ...

  3. Django Rest framework 之 认证

    django rest framework 官网 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest fra ...

  4. Django Rest framework实现流程

    目录 一 什么是restful架构 二 Django REST framework简介 三 Django REST framework原理 四 Django REST framework源码流程 五 ...

  5. Django Rest Framework API指南

    Django Rest Framework API指南 Django Rest Framework 所有API如下: Request 请求 Response 响应 View 视图 Generic vi ...

  6. Django REST framework 之JWT认证

    Json Web Token 1.JWT简介 JWT 是一个开放标准(RFC 7519),它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 H ...

  7. Django REST framework JWT学习

    1.JWT学习 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token认证机制. Json web toke ...

  8. JWT验证机制【刘新宇】【Django REST framework中使用JWT】

    JWT 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token认证机制. 什么是JWT Json web t ...

  9. Django REST Framework JWT提供的登录签发的视图

    Django REST Framework JWT提供了一个视图.在我们登录的时候,会校验用户名.密码是否正确.如果信息无误,可以返回一个JWT token.就可以简单地实现了记录用户登录状态. 用法 ...

随机推荐

  1. jQuery动画和遍历

    一.动画 1. 动画 1. 三种方式显示和隐藏元素 1. 默认显示和隐藏方式 1. show([speed,[easing],[fn]]) 1. 参数: 1. speed:动画的速度.三个预定义的值( ...

  2. 组件&Props

    组件允许你将Ui拆分为独立可复用的代码片段,并对每个片段进行独立构思.本指南只在介绍组件的相关概念.你可以参考详细组件 API. 组件,从概念上类似与JavaScript函数.它接受任意的入参(既“p ...

  3. 代码注入/文件包含 弹出Meterpreter

    主要通过 msf 中 exploit 的 web_delivery 模块来实现此功能 0x01 前提背景 目标设备存在远程文件包含漏洞或者命令注入漏洞,想在目标设备上加载webshell,但不想在目标 ...

  4. Beef搭建并通过Nginx绑定域名

    Beef和Nginx安装过程这里就不再说明了相关链接:Beef官方安装教程 1. 修改Beef的config.yaml配置文件 xss连接地址改成要绑定的域名 sudo vim /beef/confi ...

  5. 测试winform自动悬浮

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  6. JDBC 线程安全 数据库连接池

    jdbc 是线程安全的,但是,推荐一个线程用一个链接 JDBC is thread safe: It is quite OK to pass the various JDBC objects betw ...

  7. 如何学会快速调用API

    作为一名苦逼的程序员,在实现各种需求的过程中,总是需要调用各种各样的API,也就是要读各种文档.我们所要做的是弄清楚这些API的参数然后调用即可.说起来非常简单,是实际上却不是这样.现在火爆的机器学习 ...

  8. PHP获取指定分钟数的下一个整数倍

    2019-6-11 11:51:03 星期二 情景: 要定时发送邮件, 邮件数据入表时就记录下其待发送时间, 然后crontab是每分钟扫描邮件表, 找出当时那一分钟需要发送的邮件 举例: 假如有一种 ...

  9. DocumentHandler-ftl生成word

    import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io. ...

  10. Min-Max容斥及其推广和应用

    概念 Min-Max容斥,又称最值反演,是一种对于特定集合,在已知最小值或最大值中的一者情况下,求另一者的算法. 例如: $$max(a,b)=a+b-min(a,b) \\\ max(a,b,c)= ...