Python Flask实现登录、登录超时验证功能

思路:
1、用户输入账号密码,请求登录api;
2、账号不存在,返回“账号不存在”信息;
3、账号存在,判断登录密码是否相等(加密后的密码),若不相等,返回“密码不正确”信息,若相等,生成用户token(用户令牌),并且设置登录时效性,将token返回给前端设置本地缓存;
4、访问任意api,检查是否登录/登录是否超时,若未登录或登录超时,则返回“Need Login”信息,用户需要重新登录。

models:
user.py

from flask_demo.app import db
from sqlalchemy import Column,ForeignKey

class User(db.Model):
    __tablename__ = 'user'
    id = Column(db.Integer, primary_key=True, autoincrement=True) #主键id
    phone = Column(db.String(20), unique=True, nullable=False) #用户手机号
    auth_key = Column(db.String(100), nullable=False)  #加密后的密码
    nick_name = Column(db.String(20)) #用户昵称
    photo = Column(db.String(100)) #用户头像

views:
user.py


from flask_demo.app.models.user import User
from flask_demo.app import app,db
from flask import request
from flask_demo.utils.login import login_required
import json
import hashlib
import uuid

from flask_demo.utils import cache

@app.route('/login', methods=['GET','POST'])
def login():
    if request.method == 'POST':
        obj = request.get_json(force=True)
        phone = obj["phone"]
        passwd = obj["password"]
        ls = User.query.filter(User.phone == phone).first()
        if ls :
            auth_key = ls.auth_key #数据库中加密的密码
            password = pwd(passwd) #对用户登录的密码进行加密
            if auth_key != password:
                return json.dumps({"code": 200, "msg": "密码错误,请重新输入"}, indent=4, sort_keys=True, default=str,ensure_ascii=False)
            else:
                #登录成功,使用uuid4生成token
                token = uuid.uuid4().hex
                cache.savc_token(phone,token,20) #这边设置20s的登录超时时间

                return json.dumps({"code": 200, "msg": "登录成功","token":token}, indent=4, sort_keys=True, default=str, ensure_ascii=False)
        else:
            return json.dumps({"code": 200, "msg": "账号不存在"}, indent=4, sort_keys=True, default=str, ensure_ascii=False)

@app.route('/test_msg', methods=['GET'])
@login_required #登录装饰器
def test_msg():
    ls = User.query.all()
    res = []
    for x in ls:
        temp = x.__dict__
        del temp['_sa_instance_state']
        res.append(temp)

    return json.dumps({"code": 200, "data": res}, indent=4, sort_keys=True, default=str, ensure_ascii=False)

#将明文的txt转成MD5密文格式
def pwd(txt):
    md5_ = hashlib.md5()
    md5_.update(txt.encode('utf-8'))
    md5_.update('@zjw@666#$*%'.encode('utf-8'))
    return md5_.hexdigest()

utils公用组件:
cache.py,通过redis进行登录缓存,并设置登录时效性

import redis
rdb = redis.Redis(host='localhost',port=6379,db=0)

def savc_token(userid,token ,expires):

    rdb.set(userid,token,ex=expires)

def get_userid(token):
    return rdb.get(token)

check_login.py
视图装饰器
Python 有一个非常有趣的功能:函数装饰器。这个功能可以使网络应用干净整洁。 Flask 中的每个视图都是一个装饰器,它可以被注入额外的功能。你可能已经用过了 route() 装饰器。但是,你有可能需要使用你自己的装饰器。 假设有一个视图,只有已经登录的用户才能使用。如果用户访问时没有登录,则会被 重定向到登录页面。这种情况下就是使用装饰器的绝佳机会。

检查登录装饰器
让我们来实现这个装饰器。装饰器是一个包装并替换另一个函数的函数。既然源函数 已经被替代,就需要记住:要复制源函数的信息到新函数中。可以用 functools.wraps() 处理这个事情。

from functools import wraps
from flask import request
from flask_demo.utils import rdb
import json

#检查登录
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        token = request.headers.get('token')
        user = request.headers.get('user')
        print(token,user)
        if (token is None) or (not rdb.get(user)) or (token!=rdb.get(user).decode('utf-8')):
            return json.dumps({'status': 1, 'msg': 'Need Login !'}), 401
        return f(*args, **kwargs)
    return decorated_function

测试结果

用户账号不存在:
在这里插入图片描述
用户密码错误:
在这里插入图片描述
用户账号密码正确,登录成功,返回token:在这里插入图片描述
访问其他api,输入错误的token:
在这里插入图片描述
访问其他api,输入正确的token,返回数据:
在这里插入图片描述
登录超时,访问其他api:在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值