目录
生成token
里面的SECRET_KEY需要从配置文件中settings中导过来。
class UserS(APIView):
def post(self, request):
uname = request.data.get("uname")
upwd = request.data.get("upwd")
data = User.objects.filter(uname=uname, upwd=upwd).first()
# 添加一个过期时间2分钟
current_time = datetime.datetime.now()
future_time = current_time + datetime.timedelta(seconds=120)
if data is None:
return Response({
"code": 400,
"msg": "登录失败"
})
token = jwt.encode({
"uname": data.uname,
"user_id": data.id,
"time": future_time.strftime("%Y-%m-%d %H:%M:%S")
}, SECRET_KEY)
return Response({
"code": 200,
"msg": "登录成功",
"data": token
})
解析token
中间件
从写中间件,在settings文件里面的加上“MIDDLEWARE”中加上封装的
MIDDLEWARE = [
"corsheaders.middleware.CorsMiddleware",
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"从封装中一级一级导过来",
]
封装
封装一个token进行解析判断,校验。
import jwt # 导入 jwt 模块用于解析和生成 JSON Web Token
import time # 导入 time 模块用于获取当前时间
import datetime # 导入 datetime 模块用于处理日期和时间
from django.utils.deprecation import MiddlewareMixin # 导入 MiddlewareMixin 类,用于创建中间件类
from django.http import JsonResponse # 导入 JsonResponse 类用于返回 JSON 格式的响应
from Smart_Farm.settings import SECRET_KEY # 导入 SECRET_KEY 变量,用于解析 JSON Web Token
class PomitionWare(MiddlewareMixin):
def process_request(self, request):
whitelist = ["/user/"] # 定义白名单,路径在白名单中的请求将不会受到中间件的影响,不需要登录就能查看的功能路径写在这里面,登录的路径也要写在这里面
if request.path_info not in whitelist: # 检查请求路径是否在白名单中
try:
# 获取token
token = request.META.get('HTTP_AUTHORIZATION', '') # 从请求头中获取 Authorization 字段的值作为 token
print(token)
if not token: # 如果 token 为空,则说明未提供身份验证信息
return JsonResponse({ # 返回身份验证失败的响应
"code": 401,
"msg": "没有权限"
})
# 解析token
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256']) # 使用 SECRET_KEY 解析 token
shi = payload["time"] # 从解析后的 token 中获取时间字段
id = payload["user_id"] # 从解析后的 token 中获取用户ID字段
request.userid = id # 将用户ID存储在请求对象中,以便后续视图函数使用
datetime_obj = datetime.datetime.strptime(shi, '%Y-%m-%d %H:%M:%S') # 将字符串格式的时间转换为 datetime 对象
timestamp = datetime_obj.timestamp() # 将 datetime 对象转换为时间戳
now = int(time.time()) # 获取当前时间的时间戳
print(now,timestamp)
if timestamp < now: # 检查 token 中的时间是否早于当前时间
return JsonResponse({"code": 403, "msg": "token已过期"}) # 返回 token 已过期的响应
except jwt.ExpiredSignatureError:
return JsonResponse({"code": 403, "msg": "token已过期"}) # 返回 token 已过期的响应
except jwt.InvalidTokenError:
return JsonResponse({"code": 401, "msg": "无效的token"}) # 返回无效 token 的响应
except Exception as e:
return JsonResponse({"code": 402, "msg": "解析token出错"}) # 返回解析 token 出错的响应
调用
如果需要用户的id可以调用request.id。上面把用户id存到request里面了。
class Yan(APIView):
def get(self, request):
# 从request中拿到用户的id
id = request.userid
print(id)
return Response({
"code": 200,
"msg": "成功"
})