1.JWT安装配置
pip install djangorestframework-jwt==1.11.0
1.2 syl/settings.py 配置jwt载荷中的有效期设置
# jwt载荷中的有效期设置 JWT_AUTH = { # 1.token前缀:headers中 Authorization 值的前缀 'JWT_AUTH_HEADER_PREFIX': 'JWT', # 2.token有效期:一天有效 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), # 3.刷新token:允许使用旧的token换新token 'JWT_ALLOW_REFRESH': True, # 4.token有效期:token在24小时内过期, 可续期token 'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(hours=24), # 5.自定义JWT载荷信息:自定义返回格式,需要手工创建 'JWT_RESPONSE_PAYLOAD_HANDLER': 'user.utils.jwt_response_payload_handler', }
1.3 syl/settings.py JWT结合DRF进行认证权限配置
REST_FRAMEWORK = { ... # 用户登陆认证方式 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # 在 DRF中配置JWT认证 # 'rest_framework.authentication.SessionAuthentication', # 使用session时 的认证器 #'rest_framework.authentication.BasicAuthentication' # 提交表单时的认 证器 ], # 权限配置, 顺序靠上的严格 'DEFAULT_PERMISSION_CLASSES': [ # 'rest_framework.permissions.IsAdminUser', # 管理员可以访问 'rest_framework.permissions.IsAuthenticated', # 全局配置只有认 证用户可以访问接口 # 'rest_framework.permissions.IsAuthenticatedOrReadOnly', # 认证用户可以访 问, 否则只能读取 # 'rest_framework.permissions.AllowAny', # 所有用户都可以 访问 ], ..
}
1.4 user/urls.py 增加获取token接口和刷新token接口
from rest_framework.authtoken.views import obtain_auth_token from user import views from rest_framework.routers import SimpleRouter, DefaultRouter from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token # 自动生成路由方法, 必须使用视图集 # router = SimpleRouter() # 没有根路由 /user/ 无法识别 router = DefaultRouter() # 有根路由 router.register(r'user', views.UserViewSet) urlpatterns = [ path('index/', views.index), # 函数视图 path('login/', obtain_jwt_token), # 获取token,登录视图 path('refresh/', refresh_jwt_token), # 刷新token path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), # 认证地址 ] urlpatterns += router.urls # 模块地址 # print(router.urls)
1.5 在user/utils.py中从写jwt_response_payload_handler
from user.models import User def jwt_response_payload_handler(tokon,user=None,request=None,role=None): if user.first_name: name=user.first_name else: name=user.username return { 'authenticated':"true", 'id':user.id, 'role':role, 'name':name, 'username':user.username, 'email':user.email, 'tokon':tokon }
2.postman测试接口
1.编写注册接口
1.1 user/urls.py 中添加路由
urlpatterns = [ path('register/', views.RegisterView.as_view()), # 注册视图, /user/register/ ]
1.2 user/views.py 中写注册视图函数
class RegisterView(APIView): permission_classes = (AllowAny,) def post(self, request): email = request.data.get('username') passwrod = request.data.get('password') if all([email, passwrod]): pass else: return Response({'code': 9999, 'msg': '参数不全'}) rand_name = self.randomUsername() user = User(username=rand_name, email=email) user.set_password(passwrod) user.save() return Response({'code': 0, 'msg': '注册成功'}) def randomUsername(self): d = datetime.datetime.now() base = 'SYL' time_str = '%04d%02d%02d%02d%02d' % (d.year, d.month, d.day, d.hour,d.minute) rand_num = str(random.randint(10000, 99999)) return base + time_str + rand_num
2.重写django认证
2.1 syl/settings.py 中指定自定义后端认证函数位置
AUTHENTICATION_BACKENDS = [
'user.utils.EmailAuthBackend',
'django.contrib.auth.backends.ModelBackend', # 管理员admin可以登录
]
2.2 user/utils.py 中重写认证函数
# 以前使用username进行用户验证,现在修改成email进行验证 class EmailAuthBackend: def authenticate(self, request, username=None, password=None): try: user = User.objects.get(username=username) except Exception as e: user = None if not user: try: user = User.objects.get(email=username) except Exception as e: user = None if user and user.check_password(password): return user else: return None def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None
3.注册用户 & 测试登录
3.1 注册接口测试
http://192.168.56.100:8888/user/register/
http://192.168.56.100:8888/user/login/
2.1 测试登录接口,获取token