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)
    
  • 相关阅读:
    选择屏幕工具栏按钮
    通过TCODE查找SPRO路径
    程序间获取ALV显示数据(读取ALV GRID上的数据)
    CL_GUI_FRONTEND_SERVICES 使用问题
    OO ALV 后台运行时错误:Control Framework: Fatal error
    SAP EXCEL OLE常用方法和属性
    OCR论文整理
    pytorch文档阅读(一)
    目标检测论文整理
    PHP excel 科学计数法 画格子线
  • 原文地址:https://www.cnblogs.com/cpl9412290130/p/11957829.html
Copyright © 2011-2022 走看看