django + vue3 前后端token登录验证

django + vue3 前后端token登录验证

后端登录判断

def login(request):
    if request.method == 'POST':
        req = json.loads(request.body)

        user_name = req['username']
        password = req['password']

        response = {}

        user = UserInfo.objects.filter(user_name=user_name, password=password)
        if user:
            success(response)
            print("登录成功")

            # token - session 模块
            if not request.session.session_key:
                request.session.save()
                print("新会话")

            import hashlib
            import time
            request.session.set_expiry(3600 * 4)
            md5 = hashlib.md5()
            md5.update((user_name + password + "1258" + str(time.time())).encode())
            token = md5.hexdigest()
            request.session["token"] = token
            response['token'] = token
            request.session.save()
        else:
            fail(response,"用户名或密码错误")
            print("登录失败")

        res = HttpResponse(json.dumps(response))
        return res

这里说明一下关键代码。

用户密码不正确,返回错误即可。

当用户密码正确时,首先获取request.session.session_key,如果是第一次登录,那么改值为None。所以需要先创建该session。这里调用request.session.save()即可。

之后设置session过期时间,使用request.session.set_expiry(3600 * 4)。参数为秒。

计算token,这里使用自带的hashlib库随意写了一下,没考虑真实情况,

# 计算token
md5 = hashlib.md5()
md5.update((user_name + password + "1258" + str(time.time())).encode())
token = md5.hexdigest()
# 设置session中的token字段值
request.session["token"] = token
# 写入返回值,这里让前端自行写入cookie或localstorage
response['token'] = token
# 最后别忘保存session
request.session.save()

后端token验证

每次调用api或者刷新界面时,可向后端发送token,验证登录状态

def validToken(request):
    req = json.loads(request.body)
    req_token = req['token']
    res = {}
    
	# 获取session中的token
    token = request.session.get("token")
   
    # token不存在,或者token与发送来的req_token不符合,
    # 则让客户端重新登录
    if not token or token != req_token:
        fail(res,"")
    else:
        success(res)
        
    return HttpResponse(json.dumps(res))

前端登录判断

前端每次登录成功后,将token写入localstorage,这里不再列出。

这里我们看一下router前置导航守卫的写法。

这里不采用return true/false的方法控制守卫,而采用调用next()的方法控制导航,记得保证next()方法调用且仅调用一次。此外next()参数可以传递要跳转的路径。

关于导航守卫的用法请看官方文档https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

router.beforeEach((to, from, next) => {
  
  // 判断是否含有token
  const token = localStorage.getItem("token");
  if (token) {
    request({
      url: "validToken",
      method: "POST",
      data: {
        token: token,
      }
    })
      // token 有效
      .then((res) => {
        // 如果目的地是登录,跳转到主界面。否则不做理会
        if (to.name === "login") {
          next("/main");
        } else {
          next()
        }
      })
      // token 无效
      .catch((err) => {
        next("/login");
        // 清除token
        localStorage.removeItem("token");
      });
  } else {
    if (to.name !== "login") next("/login");
    else next();
  }
});

这样每次刷新的时候,就会自动判断token是否有效,否则就重新登录。

其他问题

1 前端记得配置axios,防止每次请求均为不同的session。配置如下:

import axios from "axios";
axios.defaults.withCredentials = true;

2 退出及删除session的逻辑这里不再赘述,大体相同。

posted @ 2022-03-03 21:33  aminor  阅读(1814)  评论(0)    收藏  举报
/**/ /**/