1. 程式人生 > 其它 >django + vue3 前後端token登入驗證

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的邏輯這裡不再贅述,大體相同。