电商秒杀系统-案例04-redis下的session控制

前言:
在现代的Web应用中,安全和高效的用户身份验证机制是至关重要的。本文将深入探讨基于令牌的用户登录会话机制,特别是在使用Redis进行会话管理的情景。通过这一案例实战,我们将了解令牌如何在用户身份验证过程中发挥核心作用,并确保用户会话的安全性和有效性。

令牌检查与Redis验证

用户平时会访问我们的系统,在处理任何一个请求之前,必须检查一下,这个请求是否带上了一个令牌。如果带了一个令牌,那么此时就必须在Redis里检查一下,这个令牌是否有在Redis里合法的、有效的一个session会话。如果有这个session会话,此时就可以允许这个请求被处理,因为说明这个人之前已经登录过我们的系统了,登录过后才会在Redis里放一个有效的session会话;如果说没有这个session的话,此时就会导致用户必须强制被迫登录。

用户登录与令牌发放

如果用户登录通过之后,就会返回给浏览器或者客户端一块令牌,同时在Redis里初始化好一个session会话。后续客户端就会在指定时间范围内发送请求的时候带上一块令牌,每次令牌和服务器端的session校验通过就可以执行请求。

令牌过期与强制登录

过一段时间过后,服务端的Redis里的session会话就会过期。过期了之后,又会导致你必须要重新登录,虽然你可能带上了令牌,但是一检查发现这块令牌对应的Redis里的session已经过期了。

Redis命令操作

hset把用户id和令牌存储一下,hset把用户id和过期令牌过期时间存储一下。每次访问系统都让用户带上令牌,如果令牌不存在就是没登录,hget获取存储的令牌和过期时间,如果令牌过期了也要强制登录,如果令牌校验通过,这次请求就可以通过。如果令牌要是过期了,就用hdel把存储的令牌和过期时间都删了。

代码:

package com.example.session;

import redis.clients.jedis.Jedis;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

/**
 * 示例:用户会话管理
 */
public class UserSessionManager {

    private Jedis redisClient = new Jedis("127.0.0.1");

    /**
     * 验证会话是否有效
     * @param sessionToken 会话令牌
     * @return 有效性
     */
    public boolean checkSessionValidity(String sessionToken) throws Exception {
        if(sessionToken == null || sessionToken.isEmpty()) {
            return false;
        }

        String sessionData = redisClient.hget("user_sessions", "session_token:" + sessionToken);
        if(sessionData == null || sessionData.isEmpty()) {
            return false;
        }

        String sessionExpiry = redisClient.hget("session_expiration_times", "session_token:" + sessionToken);
        if(sessionExpiry == null || sessionExpiry.isEmpty()) {
            return false;
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date sessionExpiryDate = dateFormat.parse(sessionExpiry);

        if(new Date().after(sessionExpiryDate)) {
            return false;
        }

        return true;
    }

    /**
     * 用户登录
     * @param user 用户名
     * @param pass 密码
     * @return 会话令牌
     */
    public String loginUser(String user, String pass) {
        System.out.println("登录用户:" + user + ", 密码:" + pass);
        long userId = new Random().nextInt(100000);
        String token = UUID.randomUUID().toString().replace("-", "");
        initializeSession(userId, token);
        return token;
    }

    /**
     * 初始化用户会话
     * @param userId 用户ID
     * @param token 会话令牌
     */
    public void initializeSession(long userId, String token) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR, 24);
        String sessionExpiry = dateFormat.format(calendar.getTime());

        redisClient.hset("user_sessions", "session_token:" + token, String.valueOf(userId));
        redisClient.hset("session_expiration_times", "session_token:" + token, sessionExpiry);
    }

    public static void main(String[] args) throws Exception {
        UserSessionManager sessionManager = new UserSessionManager();

        boolean isValid = sessionManager.checkSessionValidity(null);
        System.out.println("初次访问,会话验证:" + (isValid ? "通过" : "不通过"));

        String sessionToken = sessionManager.loginUser("alice","password123");
        System.out.println("登录后获得令牌:" + sessionToken);

        isValid = sessionManager.checkSessionValidity(sessionToken);
        System.out.println("再次访问,会话验证:" + (isValid ? "通过" : "不通过"));
    }
}

相关推荐

  1. 系统-案例04-redissession控制

    2024-05-14 09:44:08       37 阅读
  2. 系统架构设计-01

    2024-05-14 09:44:08       36 阅读
  3. 时候怎么使用Redis

    2024-05-14 09:44:08       39 阅读
  4. Redis实现

    2024-05-14 09:44:08       45 阅读
  5. redis(PHP版本)

    2024-05-14 09:44:08       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-14 09:44:08       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-14 09:44:08       100 阅读
  3. 在Django里面运行非项目文件

    2024-05-14 09:44:08       82 阅读
  4. Python语言-面向对象

    2024-05-14 09:44:08       91 阅读

热门阅读

  1. 100条常见的c语言bug汇总上篇3

    2024-05-14 09:44:08       36 阅读
  2. vue项目通过点击文字上传html文件,查看html文件

    2024-05-14 09:44:08       38 阅读
  3. K8S集群Etcd数据备份/恢复

    2024-05-14 09:44:08       29 阅读
  4. 数据可视化-课堂记录

    2024-05-14 09:44:08       33 阅读
  5. leetcode56--合并区间

    2024-05-14 09:44:08       21 阅读
  6. 数据结构入门 时间 空间复杂度解析

    2024-05-14 09:44:08       28 阅读
  7. LeetCode 每日一题 ---- 【994. 腐烂的橘子】

    2024-05-14 09:44:08       32 阅读
  8. ES6 笔记03

    2024-05-14 09:44:08       32 阅读
  9. keepalive 理解

    2024-05-14 09:44:08       38 阅读
  10. WebSocket概述

    2024-05-14 09:44:08       28 阅读
  11. vue3 第二十九节 (vue3 事件循环之nextTick)

    2024-05-14 09:44:08       35 阅读