pip install djangorestframework
pip install djangorestframework-jwt
pip install django-cors-headers
INSTALLED_APPS = [
...
'rest_framework',
'rest_framework.authtoken', # 设置token
'corsheaders', # 解决跨域问题
...
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
# JWT_EXPIRATION_DELTA 指明token的有效期
'JWT_AUTH_HEADER_PREFIX': 'Bearer', # 默认 JWT
# 自定义返回格式,需要手工创建
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app.views.jwt_response_payload_handler',
# JWT_RESPONSE_PAYLOAD_ERROR_HANDLER需要在库中手动设置
'JWT_RESPONSE_PAYLOAD_ERROR_HANDLER': 'app.views.jwt_response_payload_error_handler',
}
Django中jwt错误返回的是{“non_field_errors”:[“无法使用提供的认证信息登录。”]},当用户名或密码错误时,是不会去调用jwt_response_payload_handler,那么失败时调用的是什么函数了,JWT_RESPONSE_PAYLOAD_ERROR_HANDLER,但是发现这个方法并没有合到master分支,我们需要手动合并进去:
我们打开用到的虚拟环境/python3.6/site-packages/rest_framework_jwt/settings.py在IMPORT_STRINGS中添加JWT_RESPONSE_PAYLOAD_ERROR_HANDLER:
在/python3.6/site-packages/rest_framework_jwt/views.py
from rest_framework.documentation import include_docs_urls
from rest_framework_jwt.views import obtain_jwt_token
from django.conf.urls import url, include
urlpatterns = [
url(r'^userController/login/', obtain_jwt_token),
url(r'^', include_docs_urls("xxxxx")), # restframework文档接口
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), # restframework登录机制
]
JWT机制通过用户名密码,登录成功后默认返回的是token,一串加密的字符。但是我们需要返回用户的其他信息,就需要自定义,前面在JWT_AUTH 中设置了:
'JWT_RESPONSE_PAYLOAD_HANDLER': 'app.views.jwt_response_payload_handler',
假设我们新建的app名字是users,需要改成:
'JWT_RESPONSE_PAYLOAD_HANDLER': 'users.views.jwt_response_payload_handler',
users目录下views.py:
def jwt_response_payload_handler(token, user=None, request=None):
"""
登录成功后自定义返回
:param token: jwt
:param user: 当前登录用户
:param request: 请求对象
:return: 用户信息
"""
try:
rid = UsersRoles.objects.get(uid=user.id).rid # 作者设计的model
rnm = Roles.objects.get(rid=rid).rnm
results = {
"msg": "登录成功",
"code": "200",
"user": { },
"jwt": token,
}
return {'data': results}
except:
results = {
"msg": "认证失败",
"code": "10001"
}
return {'data': results}
我们已经设置了rest_framework_jwt中的代码,同上:
def jwt_response_payload_error_handler(serializer, request=None):
results = {
"msg": "用户名或者密码错误",
"code": 401,
"detail": serializer.errors
}
return {'data': results}
测试如下图:
如图登录成功会返回自定义的jwt,这个就是用来验证是否可以访问:
前端访问的时候需要加上headers:
headers: {
'Authorization': 'Bearer ' + jwt
}
Bearer是前面settings里面可以自定义的,默认为JWT,要加空格,这样才能成功访问。