Django Token
步骤:
- 新建一个token_module.py
- 新建一个authentiction_module.py
- 在app下views.py中写api
项目结构
token_module.py
import time
import base64
import hmac
def get_token(key, expire=3600):
'''
:param key: str (用户给定的key,需要用户保存以便之后验证token,每次产生token时的key 都可以是同一个key)
:param expire: int(最大有效时间,单位为s)
:return: token
'''
ts_str = str(time.time() + expire)
ts_byte = ts_str.encode("utf-8")
sha1_tshexstr = hmac.new(key.encode("utf-8"),ts_byte,'sha1').hexdigest()
token = ts_str+':'+sha1_tshexstr
b64_token = base64.urlsafe_b64encode(token.encode("utf-8"))
return b64_token.decode("utf-8")
def out_token(key, token):
'''
:param key: 服务器给的固定key
:param token: 前端传过来的token
:return: true,false
'''
# token是前端传过来的token字符串
try:
token_str = base64.urlsafe_b64decode(token).decode('utf-8')
token_list = token_str.split(':')
if len(token_list) != 2:
return False
ts_str = token_list[0]
if float(ts_str) < time.time():
# token expired
return False
known_sha1_tsstr = token_list[1]
sha1 = hmac.new(key.encode("utf-8"),ts_str.encode('utf-8'),'sha1')
calc_sha1_tsstr = sha1.hexdigest()
if calc_sha1_tsstr != known_sha1_tsstr:
# token certification failed
return False
# token certification success
return True
except Exception as e:
print(e)
authentiction_module.py
from rest_framework.authentication import BaseAuthentication
from spd_app import models
from rest_framework.exceptions import NotAuthenticated
# get_token生成加密token,out_token解密token
from spd_app.token_module import get_token, out_token
# 存储在前端的token解密比对
class TokenAuth2(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get("token")
name = request.GET.get("name")
token_obj = out_token(name, token)
if token_obj:
return
else:
raise NotAuthenticated("你没有登入")
views.py
class UserLoginViews(APIView):
# authentication_classes = [TokenAuth2] 验证是否有权限
def post(self, request, *args):
name_list = json.loads(request.body)
name = name_list[0]['username']
password = name_list[0]['password']
print(name, password)
name_data = models.User.objects.filter(username=name, password=password)
if name_data:
#token 过期时间 60
token = get_token(name, 60)
#将token返回给前端
data = {
'msg': '登录成功',
'code': 200,
'data': {
'token': token,
}
}
return Response(data)
else:
data = {
'msg': '登录失败',
'code': 400
}
return Response(data)
urls.py
from django.urls import path
from app import views
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token
urlpatterns = [
path('login', views.UserLoginViews.as_view()),
]