zoukankan      html  css  js  c++  java
  • 【翻译】REST framework JWT Auth(django rest framework-jwt)

    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

    如果除了授权标头之外还想使用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)
    
  • 相关阅读:
    为什么 PCB 生产时推荐出 Gerber 给工厂?
    Fedora Redhat Centos 有什么区别和关系?
    【KiCad】 如何给元件给元件的管脚加上划线?
    MCU ADC 进入 PD 模式后出现错误的值?
    FastAdmin 生产环境升级注意
    EMC EMI 自行评估记录
    如何让你的 KiCad 在缩放时不眩晕?
    KiCad 5.1.0 正式版终于发布
    一次单片机 SFR 页引发的“事故”
    java基础之集合
  • 原文地址:https://www.cnblogs.com/cpl9412290130/p/11957829.html
Copyright © 2011-2022 走看看