FLASK--token的生成与解析之登陆校验

一、登陆后生成token+存储到sqlite

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Date  : 2021/10/11
# @Name  : ZhouZongXin

"""

"""
import time
import base64
import hmac
from flask import make_response, request
from web.conf.sql_conf import run_sql
from web.tests.web_user_login.ht_user_login import get_tw_ht_login

# token有效期
__loginTime = 86400


def login():
    ht_userName = request.form.get("username")
    ht_password = request.form.get("password")
    res = get_tw_ht_login(ht_userName, ht_password).json()

    token = __generate_token(res['data']['adminName'], __loginTime)
    __save_token(ht_userName=res['data']['adminName'], tokens=token)
    res['data']['token'] = token
    print("登陆信息", res)
    return make_response(res)


def __save_token(ht_userName, tokens):
    """
    token存储到sqlite
    @Args:
        ht_userName: str
        tokens: str
    :param ht_userName: 用户名称
    :param tokens: token
    :return:
    """
    select_username = run_sql.select_sql("select * from login where username='%s'" % ht_userName)
    times = int(time.time())
    if select_username is None:
        sql = "insert into login('token','times','username','starts') values (?,?,?,?)"
        values_data = (tokens, times, ht_userName, 1)
        run_sql.insert_sql(sql, values_data)
    else:
        sql = "update login set token=?, times=? where username=?"
        values_data = (tokens, times, ht_userName)
        run_sql.upDate_sql(sql, values_data)


# 生成token
def __generate_token(key, expire=3600):
    """
    @Args:
        key: str (用户给定的key,需要用户保存以便之后验证token,每次产生token时的key 都可以是同一个key)
        expire: int(最大有效时间,单位为s)(self.__loginTime)
    @Return:
        state: str
    :param key:
    :param expire:
    :return:
    """
    ts_str = str(time.time() + expire)
    ts_byte = ts_str.encode("utf-8")
    sha1_tshex_str = hmac.new(key.encode("utf-8"), ts_byte, 'sha1').hexdigest()
    token = ts_str + ':' + sha1_tshex_str
    b64_token = base64.urlsafe_b64encode(token.encode("utf-8"))

    return b64_token.decode("utf-8")

二、从web获取请求头内token,并且解析token且校验

(False失败、True通过)

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Date  : 2021/10/11
# @Name  : ZhouZongXin

"""
自行生成一套token校验
"""
import time
import base64
import hmac
from flask import *

__fail_res = {
    
    "code": 401, "msg": "401 token失效,请重新登陆即可", "data": {
    
    }}


def checkToken(res):
    def wrapper():
        try:
            print(request.path)
            if request.path == '/login':
                return res()

            cookiesDict = __get_header_cookies()
            print("cookiesDict", cookiesDict)
            if cookiesDict['token']:
                print("==token校验:", __certify_token(cookiesDict['user_name'], cookiesDict['token']))
                if __certify_token(cookiesDict['user_name'], cookiesDict['token']):
                    return res()

            return __fail_res
        except Exception as error:
            print(error)
            return __fail_res

    wrapper.__name__ = res.__name__
    return wrapper


def __get_header_cookies():
    """
    获取vue-header-cookies
    :return:
    """
    Cookies = request.headers.get("Cookies")
    if Cookies is not None:
        cookiesDict = {
    
    }
        for cookieSplit in Cookies.split(';'):
            cookiesDict[cookieSplit.split("=", 1)[0]] = cookieSplit.split("=", 1)[1]
        return cookiesDict
    return Cookies


# 解析token
def __certify_token(key, token):
    """
    解析token
    @Args:
        key: str
        token: str
    @Returns:
        boolean
    :param key:
    :param token:
    :return:
    """
    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():
        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:
        return False
    return True

三、装饰器进行拦截校验(@checkToken)

from web import app
from web.tests.web_user_login import ks_user_login
from web.tests.get_my_token import checkToken


@app.route('/login', methods=["POST"])
@checkToken
def login():
    """用户名密码登陆"""
    login_data = ks_user_login.login()
    return login_data

猜你喜欢

转载自blog.csdn.net/zhouzongxin94/article/details/120711916
今日推荐