单点登录filter根据redis中的key判断是否退出

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: package com.ailk.biapp.ci.localization.cntv.filter; import java.io.IOException; import java.util.
package com.ailk.biapp.ci.localization.cntv.filter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.filter.OncePerRequestFilter;

import com.ailk.biapp.ci.localization.cntv.model.UserMessage;
import com.ailk.biapp.ci.util.JsonUtil;
import com.ailk.biapp.ci.util.RedisUtils;
import com.asiainfo.biframe.privilege.IUserSession;
import com.asiainfo.biframe.utils.config.Configure;

public class sessionFilter extends OncePerRequestFilter{

    // 登录页面
    private String LoginPage = Configure.getInstance().getProperty("com.zyzx.dmc.login.html");

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        HttpServletRequest hrequest = (HttpServletRequest) request;
        HttpSession session = hrequest.getSession();
        // 不过滤的uri
        String[] notFilter = new String[] { "login.html", ".js", "/css","/images", "/logout", "/druid", "/login","/ssoAuth" };

        // 请求的uri
        String url = request.getRequestURL().toString();
        //Token

        String token = request.getParameter("token");
//        String url = uri.replaceAll("html", "bak");
        // 是否过滤
        boolean doFilter = true;
        for (String s : notFilter) {
            if (url.indexOf(s) != -1) {
                // 如果uri中包含不过滤的uri,则不进行过滤
                doFilter = false;
                break;
            }
        }
        
        /*
         * if(uri.contains("jsp") && uri.indexOf("login.jsp") == -1) { doFilter
         * = true; }
         */
        if (doFilter) {
            // 执行过滤
            // 从session中获取登录者实体
            Object user = request.getSession().getAttribute(IUserSession.ASIA_SESSION_NAME);
            final IUserSession userSession = (IUserSession) session.getAttribute(IUserSession.ASIA_SESSION_NAME);
            final UserMessage UserMessage = (UserMessage) session.getAttribute("TOKEN");

            if (UserMessage == null) {
                //未登录状态
                if(null == token){
                    response.sendRedirect(LoginPage + "?goto=" + url);
                    return;
                //token 存在则去保存session,验证用户信息
                }else{
                    JSONObject  result = checkTokenInfo(token);
                    if(null == result){
                        response.sendRedirect(LoginPage + "?goto=" + url);
                        return;
                    }
                    //验证成功
                    if("suc".equals(result.get("result"))){
                      //正常登录
                        Map<String,String> sessionUserInfo = new HashMap<String, String>();
                        UserMessage userMessage = new UserMessage();
                        sessionUserInfo = JsonUtil.json2HashMap(result.get("userInfo").toString());
                        sessionUserInfo.put("token", token);
                        
                        String ip = request.getHeader("x-forwarded-for"); 
                        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
                            ip = request.getHeader("Proxy-Client-IP"); 
                        } 
                        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
                            ip = request.getHeader("WL-Proxy-Client-IP"); 
                        } 
                        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 
                            ip = request.getRemoteAddr(); 
                        } 
                        userMessage.setUserID(sessionUserInfo.get("user_account"));
                        userMessage.setUserName(sessionUserInfo.get("user_name"));
                        userMessage.setSessionID(sessionUserInfo.get("token"));
                        userMessage.setClientIP(ip);
                        userMessage.setToken(sessionUserInfo.get("token"));
                        request.getSession().setAttribute(IUserSession.ASIA_SESSION_NAME,userMessage);
                        request.getSession().setAttribute("TOKEN",userMessage);
                        response.sendRedirect(url);
                    }else if("fail".equals(result.get("result"))){
                        response.sendRedirect(LoginPage + "?goto=" + url);
                    }
                }
                // 如果session中不存在登录者实体,则弹出框提示重新登录
                boolean isAjaxRequest = isAjaxRequest(request);
                if (isAjaxRequest) {
                    // 设置request和response的字符集,防止乱码
                    response.setContentType("text/html;charset=UTF-8");
                    response.sendError(HttpStatus.UNAUTHORIZED.value(), "您已经太长时间没有操作,请刷新页面");
                    return;
                }
                }else {
                    token = UserMessage.getToken();
                    String booleanexist = RedisUtils.getForString(token);
                    if(booleanexist == null){
                        session.removeAttribute("TOKEN");
                        session.removeAttribute(IUserSession.ASIA_SESSION_NAME);
                        response.sendRedirect(LoginPage + "?goto=" + url);
                        return;
                    }
                    // 如果session中存在登录者实体,则继续
                    filterChain.doFilter(request, response);
                      }
        } else {
            // 如果不执行过滤,则继续
            filterChain.doFilter(request, response);
        }
    }

    /**
     * 判断是否为Ajax请求 <功能详细描述>
     * 
     * @param request
     * @return 是true, 否false
     * @see [类、类#方法、类#成员]
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String header = request.getHeader("X-Requested-With");
        if (header != null && "XMLHttpRequest".equals(header))
            return true;
        else
            return false;
    }
    /**
     * 
     * 验证Token是否存在
     * @param tokenValue
     * @return
     * @throws IOException
     */
    private JSONObject checkTokenInfo(String tokenValue) throws IOException {
        String checkUrl = Configure.getInstance().getProperty("com.zyzx.aqs.tokenCheckUrl")+tokenValue;
        HttpClient httpclient = new HttpClient();
        GetMethod httpget = new GetMethod(checkUrl);
        try {
            httpclient.executeMethod(httpget);
            String result = httpget.getResponseBodyAsString();
            JSONObject json = JSONObject.fromObject(result);
            return json;
        } finally {
            httpget.releaseConnection();
        }
    }
    
}

其实可以直接用userSession 但由于项目已经封装了,所以再创建个UserMessage实体类,在登录后将token存入session,当从redis中通过key获取token为空时,便清除userSession,跳转到指定系统页面。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
存储 缓存 NoSQL
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
【Azure Redis 缓存】关于Azure Cache for Redis 服务在传输和存储键值对(Key/Value)的加密问题
|
2天前
|
NoSQL Unix Redis
Redis 键(key)
10月更文挑战第15天
6 1
|
9天前
|
缓存 监控 负载均衡
如何解决Redis热点Key问题?技术干货分享
【10月更文挑战第2天】在Redis的使用过程中,热点Key问题是一个常见的性能瓶颈。热点Key指的是那些被频繁访问的Key,它们可能导致Redis服务器的负载不均衡,进而影响整体性能。本文将深入探讨热点Key问题的成因、影响以及多种解决方案,帮助读者在实际工作中有效应对这一挑战。
18 3
|
18天前
|
NoSQL Redis
redis 的 key 过期策略是怎么实现的(经典面试题)超级通俗易懂的解释!
本文解释了Redis实现key过期策略的方式,包括定期删除和惰性删除两种机制,并提到了Redis的内存淘汰策略作为补充,以确保过期的key能够被及时删除。
37 1
|
27天前
|
存储 缓存 NoSQL
Redis 大 Key 对持久化的影响及解决方案
Redis 大 Key 对持久化的影响及解决方案
31 1
|
1月前
|
存储 缓存 NoSQL
Redis中大Key与热Key的解决方案
在工作中,Redis作为一款高性能缓存数据库被广泛应用,但常遇到“大key”和“热key”问题。“大key”指单个键包含大量数据,导致内存消耗高、性能下降及持久化效率降低;“热key”则是频繁访问的键,会引起CPU占用率高、请求阻塞等问题。本文详细分析了这些问题的定义、影响、原因,并提供了相应的解决方案,如合理设置缓存时间和数据结构、拆分大key、采用热点数据分片等方法。
157 4
Redis中大Key与热Key的解决方案
|
1月前
|
缓存 NoSQL PHP
使用PHP-redis实现键空间通知监听key失效事件的技术与代码示例
通过上述方法,你可以有效地在PHP中使用Redis来监听键空间通知,特别是针对键失效事件。这可以帮助你更好地管理缓存策略,及时响应键的变化。
79 3
|
27天前
|
存储 缓存 NoSQL
Redis过期Key的清理机制
Redis过期Key的清理机制
38 0
|
2月前
|
存储 NoSQL Redis
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
【Azure Developer】一个复制Redis Key到另一个Redis服务的工具(redis_copy_net8)
|
2月前
|
NoSQL Redis
Redis——大批量删除redis的key
Redis——大批量删除redis的key
56 1