diff --git a/EduSystemServer/API/middle.py b/EduSystemServer/API/middle.py index 30bc1b0..71f0640 100644 --- a/EduSystemServer/API/middle.py +++ b/EduSystemServer/API/middle.py @@ -1,23 +1,29 @@ +import jwt from django.http import JsonResponse +from EduSystemServer.settings import TOKEN_KEY +from EduSystemServer.utils import ResponseUtil -class AuthMiddleware: - """ - 验证权限登录中间件 - """ +class JWTMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): - path = request.path - if path in [ - "/login", - ]: + # 检查请求的路径是否是登录路由,如果是,放行 + if request.path == '/login': response = self.get_response(request) return response - - session = request.session - if not session.get("username") and not session.get("type"): - return JsonResponse({"code": -1, "msg": "not login!"}, status=401) + # 从请求头中获取 Token + token = request.META.get('HTTP_AUTHORIZATION', '') + try: + # 验证 Token + payload = jwt.decode(token, TOKEN_KEY, algorithms=['HS256']) + # 将解码后的 Token 数据存储在 request 中,以便视图可以访问 + request.jwt_payload = payload + except jwt.ExpiredSignatureError: + return JsonResponse(ResponseUtil.error("登录失效!"), status=401) + except jwt.DecodeError: + return JsonResponse(ResponseUtil.error("登录失效!"), status=401) + # 继续处理请求 response = self.get_response(request) - return response + return response \ No newline at end of file diff --git a/EduSystemServer/API/views.py b/EduSystemServer/API/views.py index 28127b1..e34babd 100644 --- a/EduSystemServer/API/views.py +++ b/EduSystemServer/API/views.py @@ -1,5 +1,7 @@ import json +from datetime import datetime, timedelta +import jwt from django.shortcuts import render from django.http import JsonResponse, HttpResponse @@ -8,7 +10,22 @@ from django.views.decorators.csrf import csrf_exempt from Student.models import * from teacher.models import Teacher from EduSystemServer.utils import ResponseUtil +from EduSystemServer.settings import TOKEN_KEY +# 用户登录成功后生成 JWT Token +def generate_jwt_token(user, _type): + # 设置 Token 的有效期 + expiration_time = datetime.utcnow() + timedelta(hours=1) + + # 构建 Token 数据 + payload = { + 'type': _type, + 'username': user.username, + 'exp': expiration_time + } + # 使用密钥对数据进行签名生成 Token + token = jwt.encode(payload, TOKEN_KEY, algorithm='HS256') + return token @csrf_exempt def login(request): @@ -19,18 +36,18 @@ def login(request): student = Student.objects.filter(username=username, password=password).first() if student: - request.session["username"] = student.username - request.session["type"] = "student" - result = ResponseUtil.ok(student.to_dict(), "login success!") + result = student.to_dict() + result = ResponseUtil.ok(result, "login success!") + result["token"] = generate_jwt_token(student, "student").decode("utf-8") else: result = {"code": -1, "message": "username or password error!"} elif _type == "teacher": teacher = Teacher.objects.filter(username=username, password=password).first() if teacher: - request.session["username"] = teacher.username - request.session["type"] = "teacher" - result = ResponseUtil.ok(teacher.to_dict(), "login success!") + result = teacher.to_dict() + result = ResponseUtil.ok(result, "login success!") + result["token"] = generate_jwt_token(teacher, "teacher").decode("utf-8") else: result = ResponseUtil.error("username or password error!") else: @@ -40,8 +57,8 @@ def login(request): @csrf_exempt def get_user_info(request): - _type = request.GET.get("type") - username = request.GET.get("username") + _type = request.jwt_payload.get("type") + username = request.jwt_payload.get("username") if _type == "student": student = Student.objects.filter(username=username).first() result = ResponseUtil.ok(student.to_dict()) diff --git a/EduSystemServer/EduSystemServer/settings.py b/EduSystemServer/EduSystemServer/settings.py index 5f95221..d12448c 100644 --- a/EduSystemServer/EduSystemServer/settings.py +++ b/EduSystemServer/EduSystemServer/settings.py @@ -9,7 +9,7 @@ https://docs.djangoproject.com/en/2.2/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/2.2/ref/settings/ """ - +import datetime import os @@ -59,7 +59,7 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', - # 'API.middle.AuthMiddleware', + 'API.middle.JWTMiddleware', ] @@ -151,3 +151,5 @@ CORS_ALLOW_HEADERS = ( 'x-requested-with', 'Cookie', # 添加Cookie到允许的头部 ) + +TOKEN_KEY = "eduSystem" \ No newline at end of file diff --git a/EduSystemServer/Student/views.py b/EduSystemServer/Student/views.py index 3c3d2c1..cb2ed17 100644 --- a/EduSystemServer/Student/views.py +++ b/EduSystemServer/Student/views.py @@ -209,7 +209,7 @@ def get_grade(request): if not request.method == "GET": return ResponseUtil.error("request method error!") try: - username = request.GET.get("username") + username = request.jwt_payload.get("username") student = Student.objects.filter(username=username).first() grade__all = SC.objects.filter(sid=student.sid).values("sid", "sid__name", "cid__name", "cid__type", "cid__credit", "cid__tid__name", "middle_grade", "end_grade").all() diff --git a/EduSystemServer/course/views.py b/EduSystemServer/course/views.py index c189e05..6ee8de6 100644 --- a/EduSystemServer/course/views.py +++ b/EduSystemServer/course/views.py @@ -107,7 +107,7 @@ def search_course(request): def get_course_by_student_id(request): if not request.method == "GET": return JsonResponse(ResponseUtil.error("request method error!")) - s_username = request.GET.get("username") + s_username = request.jwt_payload.get("username") student = Student.objects.filter(username=s_username).first() sc_list = SC.objects.filter(sid=student.sid).values("sid__name", "cid__name", "cid__tid__name", "sid", "cid", "cid__credit", "cid__tid__title", "cid__tid__dept", "cid__type").all()