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. linux命令之------部分细节点

    创建文件夹/文件命令以及清除模式 mkdir +文件夹名字 touch +文件名字 rm -fr 删除文件,文件夹 -f强制删除 -r是递归 查询linux下所有启动的线程: ps -ef|grep ...

  2. Codeforces 161.D. Distance in Tree-树分治(点分治,不容斥版)-树上距离为K的点对数量-蜜汁TLE (VK Cup 2012 Round 1)

    D. Distance in Tree time limit per test 3 seconds memory limit per test 512 megabytes input standard ...

  3. js之select三级联动

    效果图如下: 代码逻辑梳理:层层递进,比如选择了课程后,将对应的课程id保存,然后点击选择章时自动触发对应的时间,根据这个课程ID获取其下面的章信息.其它的如节等,同理. 代码说明:如下代码不规范,可 ...

  4. BaiduPCS-Go的安装及使用

    BaiduPCS-Go的安装及使用 linux下会提示输入验证码,浏览器打开验证码url,多输入几次 Contents [hide] 一. 软件下载及安装 二. 软件的使用 1. 账号登录与退出 2. ...

  5. 配置Zuul代理下游的认证

    配置Zuul代理下游的认证 您可以通过proxy.auth.*设置控制@EnableZuulProxy下游的授权行为.例: application.yml proxy: auth: routes: c ...

  6. httpcomponents 发送get post请求

    引入的包为: <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <de ...

  7. web页面引入字体

    一.常见web字体 TrueType (.ttf) Windows和Mac系统最常用的字体格式,其最大的特点就是它是由一种数学模式来进行定义的基于轮廓技术的字体,这使得它们比基于矢量的字体更容易处理, ...

  8. 【基础】Qt SCXML Calculator QML Example

    Qt SCXML Calculator QML Example 这个系统自带的例子原本主要是用来说明SCXML机制的,但是由于计算器的经典和简洁,我认为用来练习QML非常合适,原本的例子还有一些问题, ...

  9. 巧用List.stream()方法对List做处理

    List.steam()的强大之处在此不做赘述. 直接进入主题: 1.过滤Bean List中,某些字段等于指定值的所有行 List<Member> list = itemsArray.t ...

  10. ThinkPhp5 数据迁移(think-migration)

    ThinkPhp5 数据迁移(think-migration)   在thinkphp5中提供了数据迁移工具(think-migration),它是机遇phinx开发(文档地址:http://docs ...