环境要求:

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)

我的环境:

Python 3.6
Django 1.11.11
Django REST framework 3.8.2

具体步骤

1.安装
pip install djangorestframework-jwt

2.配置
在settings 中将“JSONWebTokenAuthentication”,添加到 Django REST 框架中“DEFAULT_AUTHENTICATION_CLASSES”,如下:

 1 # rest_framework settings
 2 REST_FRAMEWORK = {
 3 # REST framework Auth
 4 # 'DEFAULT_PERMISSION_CLASSES': (
 5 #    'rest_framework.permissions.IsAuthenticated',
 6 # ),
 7   'DEFAULT_AUTHENTICATION_CLASSES': (
 8   'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
 9   'rest_framework.authentication.SessionAuthentication',
10   'rest_framework.authentication.BasicAuthentication',
11 ),
12 }

 

在users/urls.py 中添加url路由,以启用使用用户名和密码通过POST获取token

1 from rest_framework_jwt.views import obtain_jwt_token
2 urlpatterns = [
3   ...,
4   url(r'^auths/$', obtain_jwt_token, name='auths')
5 ]

 

测试使用用户名test01 和密码12345678 在终端中执行下面的操作来测试是否正常工作

curl -X POST -d "username=test01&password=12345678" http://127.0.0.1:8000/users/auths/

也可以使用另外一种命令通过JSON数据 来请求获取token

curl -X POST -H "Content-Type: application/json" -d '{"username":"test01","password":"12345678"}' http://127.0.0.1:8000/users/auths/

结果是一样的
拿到这个token 后,就可以使用这个token 去访问受保护的资源了,但是必须要设置Authorization:JWT <your_tojen> 的请求头信息

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

如果想了解更多的curl 命令,请查看 https://www.cnblogs.com/duhuo/p/5695256.html#4098907

其他设置(根据自身需求在settings中设置JWT_AUTH)
以下为所有可用的默认值

 1 JWT_AUTH = {
 2 'JWT_ENCODE_HANDLER':
 3 'rest_framework_jwt.utils.jwt_encode_handler',
 4 
 5 'JWT_DECODE_HANDLER':
 6 'rest_framework_jwt.utils.jwt_decode_handler',
 7 
 8 'JWT_PAYLOAD_HANDLER':
 9 'rest_framework_jwt.utils.jwt_payload_handler',
10 
11 'JWT_PAYLOAD_GET_USER_ID_HANDLER':
12 'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler',
13 
14 'JWT_RESPONSE_PAYLOAD_HANDLER':
15 'rest_framework_jwt.utils.jwt_response_payload_handler',
16 
17 'JWT_SECRET_KEY': settings.SECRET_KEY,
18 'JWT_GET_USER_SECRET_KEY': None,
19 'JWT_PUBLIC_KEY': None,
20 'JWT_PRIVATE_KEY': None,
21 'JWT_ALGORITHM': 'HS256',
22 'JWT_VERIFY': True,
23 'JWT_VERIFY_EXPIRATION': True,
24 'JWT_LEEWAY': 0,
25 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
26 'JWT_AUDIENCE': None,
27 'JWT_ISSUER': None,
28 
29 'JWT_ALLOW_REFRESH': False,
30 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
31 
32 'JWT_AUTH_HEADER_PREFIX': 'JWT',
33 'JWT_AUTH_COOKIE': None,
34 }

 

其中允许修改的选项有:

JWT_SECRET_KEY
这个是用于签属JWT 的密钥,默认是使用项目的settings.SECRET_KEY,如果需要修改,需确保设置的是安全的,非公开的

JWT_GET_USER_SECRET_KEY
这个个JWT_SECRET_KEY 的更强大的版本。是根据用户定义的,因此如果token 被泄露,可以让所有者轻松更改。更改此值将给定用户的所有令牌都无法使用。值是一个函数,接收用户作为唯一参数,并返回它的密钥,默认是None

JWT_VERIFY
如果验证密钥是错误的,将会抛出一个DecodeError的错误,如果你还想获得荷载里面的内容,可以将这个值设置成False,默认是True

JWT_VERIFY_EXPIRATION
设置该值为False 将会关闭过期验证('JWT_EXPRIATION_DELTA'将无效),如果没有过期验证,JWT 将永远存在,意味着攻击者可以无限期地使用泄露的令牌。默认为True

JWT_LEEWAY
这允许您验证过去但不是很远的过期时间。 例如,如果您有一个JWT有效负载,其过期时间设置为创建后30秒,但您知道有时您将在30秒后处理它,您可以设置10秒的余地以获得一些余量。默认为 0 秒

JWT_EXPIRATION_DELTA
值是Python 的一个datetime.timedelta 的实例对象。将添加datetime.utcnow() 来设置到期时间
默认是 datetime.timelta(seconds=300) (300秒,即5分钟)

JWT_AUDIENCE
如果存在,值就是一个字符串,用来验证JWT 里的“aud”字段
默认是None (如果JWT 里面存在aud 字段,此值使用默认值,则会验证失败)

JWT_ISSUER
如果存在,值就是一个字符串,用来验证JWT 里面的“iss”字段
默认是None(不建议在JWT 中设置此字段)

JWT_ALLOW_REFERSH
开启令牌刷新功能,被“rest_framework_jwt.views.obtain_jwt_token” 签发的令牌将会有一个“orig_iat”字段
默认是False 不刷新令牌

JWT_REFERSH_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 方式与默认的有效负载处理程序不同,请实现此功能让username 从有效负载中获取

JWT_RESPONSE_PAYLOAD_HANDLER
负责控制登录或刷新后响应返回的数据,可以重新定义函数以覆盖响应默认返回的内容,比如用户的序列化表示:

1 def jwt_response_payload_handler(token, user=None, request=None):
2   return {
3     'token': token,
4     'user': UserSerializer(user, context={'request': request}.data
5   }

默认返回的是 {’token‘: token}

JWT_AUTH_HANDER_PREFIX
请求时,“Authorization” 请求头字段值的前缀,默认是 JWT ,用于令牌请求的头的另一个常见的前缀使用的是“Bearer”

JWT_AUTH_COOKIE
如果你除了“Authorization”请求头之外还要使用http Cookie 放到令牌作为有效传输,你可以在这设置一个字符串作为Cookie 的名称,这个名称将在生成令牌时存在在响应头,如果进行了设置,则令牌校验请求的时候也会查看这个名称。如果请求头中同时存在这个Cookie 名称和“Authorization”这两个字段,将以“Authorization” 为主要校验手段。
默认是None ,创建令牌时使用默认值,则在验证的时候也就接收请求中的Cookie 去验证

 

手动创建新令牌
有时希望手动生成令牌,例如再创建账户后立即将令牌返回给用户,可以添加以下逻辑

1 from rest_framework_jwt.settings import api_settings
2 
3 jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
4 jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
5 payload = jwt_payload_handler(user)
6 token = jwt_encode_handler(payload)

 

不常用的设置

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

JWT_PRIVATE_KEY
这是一个类型的对象cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey。它将用于签署JWT的签名组件。JWT_SECRET_KEY设置时将覆盖。阅读文档以获取更多详细信息。请注意,JWT_ALGORITHM必须设置为一个RS256,RS384或RS512。
默认是None

JWT_ALGORITHM
可能的值是PyJWT中用于加密签名的任何支持算法。
默认是"HS256"。

 

参考资料:http://getblimp.github.io/django-rest-framework-jwt/