vue + django 通过token 进行验证
一、思路说明
1、前端通过登录表单进行提交
2、后端接收到请求后对账号密码进行验证
3、验证通过后生成token,将账号和token作为键值对存入redis,并返回给前端
4、前端接收到token值存入sessionStorage,下次请求携带token
二、具体实现
- 前端部分代码
login() {
//请求前验证合法性
this.$refs.ruleFormRef.validate(async valid => {
if (!valid) return;
const { data: res } = await this.$http.post("login/", this.ruleForm);
console.log(res)
if (res.status !== "200") return this.$message.error("登陆失败");
//提示登录成功
this.$message.success("登陆成功!");
//获取token 并保存到sessionStorage
window.sessionStorage.setItem("token", res.token);
//跳转到首页
this.$router.push('/home');
})
}
- 后端部分代码
common/token/my_token.py
import time
from django.core import signing
import hashlib
from django.core.cache import cache
HEADER = {'typ': 'JWP', 'alg': 'default'}
KEY = 'LIN_TIAN_LAI'
SALT = 'api-shop.14143.cn'
TIME_OUT = 30 * 60 # 30min
def encrypt(obj):
"""加密"""
value = signing.dumps(obj, key=KEY, salt=SALT)
value = signing.b64_encode(value.encode()).decode()
return value
def decrypt(src):
"""解密"""
src = signing.b64_decode(src.encode()).decode()
raw = signing.loads(src, key=KEY, salt=SALT)
print(type(raw))
return raw
def create_token(username):
"""生成token信息"""
# 1. 加密头信息
header = encrypt(HEADER)
# 2. 构造Payload
payload = {"username": username, "iat": time.time()}
payload = encrypt(payload)
# 3. 生成签名
md5 = hashlib.md5()
md5.update(("%s.%s" % (header, payload)).encode())
signature = md5.hexdigest()
token = "%s.%s.%s" % (header, payload, signature)
# 存储到缓存中
cache.set(username, token, TIME_OUT)
return token
def get_payload(token):
payload = str(token).split('.')[1]
payload = decrypt(payload)
return payload
# 通过token获取用户名
def get_username(token):
payload = get_payload(token)
return payload['username']
def check_token(token):
username = get_username(token)
last_token = cache.get(username)
if last_token:
return last_token == token
return False
if __name__ == "__main__":
print(create_token('ading2021'))
views.py
from common.token.my_token import create_token
def add_header(response):
"""响应添加响应头,支持前端跨域"""
response["Access-Control-Allow-Origin"] = "http://localhost:8080"
response["Access-Control-Allow-Methods"] = "POST, GET"
response["Access-Control-Max-Age"] = "1000"
response["Access-Control-Allow-Headers"] = "*"
response['Access-Control-Allow-Credentials'] = 'true'
return response
# 登录验证
def login(request):
# 因为是通过接口POST,数据都在请求体里面
body = str(request.body, encoding="utf-8")
data = eval(body)
user_str = data['user_str']
password = data['password']
u_type = user_type(user_str)
print(u_type)
# 先判断用户是否存在, 如果用户存在再判断密码是否正确·
try:
if u_type == 'phone_number':
obj = UserMain.objects.get(phone_number=user_str)
user_str = obj.user_name
elif u_type == 'email':
obj = UserMain.objects.get(email=user_str)
user_str = obj.user_name
else:
obj = UserMain.objects.get(user_name=user_str)
if md5(password) == obj.password:
# 密码验证通过后生成token
token = create_token(user_str)
user = json.dumps({**model_to_dict(obj), **success_message, **{'token': token}}) # 可以通过这种方法把多个字典进行合并。
response = HttpResponse(user)
response = add_header(response)
return response
else:
response = HttpResponse(json.dumps(auth_fail_message))
response = add_header(response)
return response
except UserMain.DoesNotExist:
response = HttpResponse(json.dumps(auth_fail_message))
response = add_header(response)
return response