美文网首页
redis模块操作 Redis

redis模块操作 Redis

作者: 运维开发_西瓜甜 | 来源:发表于2020-04-01 18:55 被阅读0次

本文链接:https://www.jianshu.com/p/721d54e83190
作者:西瓜甜

1. 安装包

pip3 install redis

2. 连接

In [1]: import redis

In [2]: rs = redis.StrictRedis(host='192.168.1.37', port=6379,db=0,decode_responses=True
In [3]: rs.set("QF", "www.qfedu.com")
Out[3]: True

In [4]: rs.get("QF")
Out[4]: 'www.qfedu.com'
  • db=0 指定使用那个数据库, 0-15 共 16 个,默认是 0
  • decode_responses=True redis 返回值默认是二进制 bytes 类型,设置为 True 可直接返回字符串,默认使用 utf-8

3. 基本操作

4.1 set 在 Redis 中设置键值对值,默认,不存在则创建,存在则修改

set(name, value, ex=None, px=None, nx=False, xx=False)
"""
 参数:
         ex,过期时间(秒)
         px,过期时间(毫秒)
         nx,假如设置为True,则只有 name 不存在时,当前 set 操作才执行
         xx,假如设置为True,则只有 name 存在时,当前 set 操作才执行
"""
  • 示例
In [121]: rs.set("name", "shark",ex=50)
Out[121]: True

In [122]: rs.ttl("name")  # 查看过期时间
Out[122]: 41

In [123]: rs.get("name")
Out[123]: 'shark'

4.2 setex 设置键值对,并设置过期时间(单位秒)

setex(name,  time, value)

"""
 参数:
     time,过期时间(数字秒)
"""
  • 示例
In [26]: rs.setex('login', 30, 1)
Out[26]: True

In [27]: rs.ttl("login")
Out[27]: 27

In [28]: rs.get("login")
Out[28]: '1'

4.3 Hash 操作

Redis 中的 Hash 数据,很想 Python 中嵌套的字典 : {"n1": {"k1": "v1", "k2", "v2"}}

Hash 示意图

使用场景

比如我们想存储用户的登录信息
一般用户的登录信息有一下几点:

  • 用户名 name
  • 加密的密码 password
  • 会话 session_id
  • 会话过期时间 expiration_date

那现在就来模拟一下一个用户从登录到登出(过期)的情况

4.3.1 具体实现

当用户登录的时候我们需要添加多个数据,可以使用 hmset()方法

"""
hmset(name, mapping)
name 就是一个hash 的名字 , mapping 就是一个字典
在name对应的hash中批量设置键值对,没有的 key 就创建,已存在的 key 修改
"""

In [78]: import random, string, hashlib

In [79]: name="shark"

In [80]: base_str = f"{string.digits + string.ascii_letters}"

In [81]: sessid = ''.join(random.sample(base_str, 20))

In [82]: sessid
Out[82]: 'SFMNr3jzJZTRYLy64qfb'

In [83]: password = hashlib.md5("QFedu123!".encode('utf-8'))

In [84]: password = password.hexdigest()

In [85]: password
Out[85]: '19b169cff70f61b4e80663757025a17d'

In [86]: user_info = {"name": name, "password": password, "sessid": sessid}

In [87]: rs.hmset(name, user_info)
Out[87]: True

In [88]: rs.setex(f"{name}_sessid",86400,sessid))
Out[88]: True

每次用户再次跳转页面或者发送新的请求时,我们都应该查看他的登录状态和会话是否超时。

首先,获取 redis 中 Hash 数据使用的是 hget()hmget方法

hget(name,key)

在name对应的hash中获取根据key获取value

In [155]: rs.hget(name, 'sessid')
Out[155]: 'SFMNr3jzJZTRYLy64qfb'

hmget(name, keys, *args)

在name对应的hash中获取多个key的值
参数:
name,reids对应的name
keys,要获取key集合,例如:['k1', 'k2', 'k3']
*args,要获取的key,例如:k1,k2,k3

In [156]: rs.hmget(name, ["name", "sessid", "login"])
Out[156]: ['shark', 'SFMNr3jzJZTRYLy64qfb', 'True']

In [157]: name, sessid, login = rs.hmget(name, ["name", "sessid", "login"])

In [158]: login
Out[158]: 'True'

模拟登录状态OK, 需要进一步检查 会话是否超时的情况

In [164]: rs.hmset(name, {"sessid": '', "login": "False"})
Out[164]: True

In [165]: rs.hget(name,"sessid")
Out[165]: ''

In [166]: rs.hget(name,"login")
Out[166]: 'False'

作业练习:

编写一个脚本,把上面我们讲的用户信息存入到 Redis 中。
实现一个简单的登录验证功能。

  1. 提示用户登录,用户输入用户名和密码,首先验证用户名密码

  2. 用户名密码错误,请重新登录。

  3. 用户名密码正确就继续验证,会话是否存在或者是否过期

  4. 会话过期或者不存在,则重新设置或添加会话信息, 并显示登录成功

  5. 不过期,就显示继续操作

流程图:

image.png

运行时的效果


image.png

参考源码

配置文件

settings.py

CACHE_SERVER = {
    "host": '127.0.0.1',
    "port": 6379,
    'db': 0
}

连接 Redis 模块

cache.py

import redis

from settings import CACHE_SERVER

# 缓存 Redis 连接信息
redis_host, redis_port = CACHE_SERVER.get("host"), CACHE_SERVER.get("port")
redis_db = CACHE_SERVER.get("db")

rs = redis.StrictRedis(
    host=redis_host,
    port=redis_port,
    db=redis_db
)

程序源码

import random, string, hashlib

from cache import rs

def generate_sessid():
    """生产随机字符串
    Return: 返回 session id
    """
    
    # 获取基本的字符串0-9 a-z A-Z
    base_str = f"{string.digits + string.ascii_letters}"
    # 拼接
    sessid = ''.join(random.sample(base_str, 20))
    return sessid
    
def hash_pwd(pwd):
    """传入一串字符,进行 MD5 计算
    Keyword arguments:
    pwd -- 字符串
    Return: md5 加密值
    """
    
    password = hashlib.md5(pwd.encode('utf-8'))
    return password.hexdigest()

def save_session(name, pwd, sessid=''):
    """组合用户会话信息,并存入缓存
    
    Keyword arguments:
    name -- 用户名
    pwd -- 加密过的密码
    sessid -- 会话 id
    Return:
    """
    user_info = {"name": name, "password": pwd, "sessid": sessid}
    rs.hmset(name, user_info)
    rs.setex(f"{name}_sessid",86400,sessid)

def auth(name, pwd):
    source_pwd = hash_pwd("QFedu123!")
    if name == 'shark' and pwd == source_pwd:
        return True
    else:
        return False


if __name__ == "__main__":
    while True:
        inp = input("输入用户名和密码,中间用空格隔开,比如: shark 123\n>>:")
        user_pwd = inp.split()
        if len(user_pwd) == 2:
            name, pwd = user_pwd

        else:
            print("格式错误")
            continue
        
        sessid = generate_sessid()
        pwd = hash_pwd(pwd)
        
        # 判断用户名和密码是否正确
        if auth(name, pwd):
            # 检查会话是否超时
            ttl = rs.ttl(f"{name}_sessid")
            if ttl >= 1:
                print("会话有效")
                print("继续操作")
                break
            else:
                # 会话不存在或者失效,存入新的会话
                save_session(name, pwd,sessid=sessid)
                print("登录成功")
                break
        else:
            print("用户名或者密码错误")

相关文章

网友评论

      本文标题:redis模块操作 Redis

      本文链接:https://www.haomeiwen.com/subject/nmnauhtx.html