分布式环境下用redis模拟session

来源:互联网 发布:南风知我意琰阙百度云 编辑:程序博客网 时间:2024/06/07 12:18

首先为什么使用redis?

因为分布式有不同服务器的缘故,如果你安照一般方式存储session,那么你的session会保存在某一台服务器上,如果你的下一个请求并不是访问这台服务器,那么会发生读取不到session的情况

redis存储的实现方案:

第一种 是使用容器拓展来实现,一般都是通过容器插件来实现,例如基于Tomcat的tomcat-redis-session-manager,基于Jetty的jetty-session-redis等等。好处是对项目来说是透明的,无需更改代码,但是目前还不支持Tomcat8。个人觉得由于过于依赖容器,,一旦更换容器或者容器升级,那又得重新来过。而且代码并不在项目中,对于开发者的维护也是个麻烦。

第二种 是自定义会话管理的工具类,这样的话灵活性很大,可以根据自身需求来实现,但是需要额外的开发时间

第三种是使用框架的会话管理工具,例如spring-session,shiro等,可以理解是替换了servlet那一套会话管理,不依赖容器,不用改动代码。如果采用spring-session的话,使用的是spring-data-redis那一套连接池,prefect,不过前提是你得用spring框架。至于shiro,那是一个十分成熟,强大易用的安全框架,学习成本比spring-session来的要多一些。

下面我们介绍一下第二种方式的实现

要注意的是为什么前端用ajax的方式登录,因为把模拟的session信息用存到redis后,需要在本地存入userId和token来作为用户的标识,通过这个标识去redis里验证该用户是否登录,从而获取redis中的用户登录信息,但是分布式中多个系统对应多个domain,所以login模块生成的userId和token要想每个系统都用,必须每个系统都生成自己的cookie信息,java端无法为每个系统生成一份cookie所以只能在前端用iframe的方式为每个系统生成一份cookie

下面是详细代码

redis的配置:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"    xmlns:mongo="http://www.springframework.org/schema/data/mongo" xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="http://www.springframework.org/schema/context             http://www.springframework.org/schema/context/spring-context.xsd             http://www.springframework.org/schema/data/mongo             http://www.springframework.org/schema/data/mongo/spring-mongo-1.7.xsd             http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans.xsd">    <!-- redis缓存部分 -->    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">        <property name="maxIdle" value="${redis.maxIdle}" />        <property name="maxTotal" value="${redis.maxTotal}" />        <property name="maxWaitMillis" value="${redis.maxWaitMillis}" />        <property name="testOnBorrow" value="${redis.testOnBorrow}" />    </bean>    <bean id="redisConnectionFactory"        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"        p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"        p:pool-config-ref="poolConfig" />    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">        <property name="connectionFactory" ref="redisConnectionFactory" />    </bean>    <!--加载redis -->    <bean id="redisService" class="com.maigangle.b2b.common.redis.RedisSpringServiceImpl">        <!-- 控制redis开关 -->        <property name="isUse" value="true"></property>    </bean></beans>

RedisSpringServiceImpl.java

package com.maigangle.b2b.common.redis;import java.io.UnsupportedEncodingException;import java.util.ArrayList;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.dao.DataAccessException;import org.springframework.data.redis.RedisConnectionFailureException;import org.springframework.data.redis.connection.RedisConnection;import org.springframework.data.redis.core.RedisCallback;import org.springframework.data.redis.core.RedisTemplate;import com.alibaba.fastjson.JSON;import com.maigangle.b2b.common.exception.CommonException;/** * redis接口实现 *  * @author  * @since  * @version 1.0 * */public class RedisSpringServiceImpl implements RedisSpringService {    private static String redisCode = "utf-8";    private boolean isUse; // redis开关    private byte[] getBytes(String str) {        try {            return str.getBytes(redisCode);        } catch (UnsupportedEncodingException e) {            return str.getBytes();        }    }    public boolean isUse() {        return isUse;    }    public void setIsUse(boolean isUse) {        this.isUse = isUse;    }    @Autowired    private RedisTemplate<String, String> redisTemplate;    public void pub(String channel, String param) {        if (!isUse)            return;        redisTemplate.convertAndSend(channel, param);    }    /**     * @param key     */    public Long del(final String... keys) {        if (!isUse)            return null;        try {            long re = redisTemplate.execute(new RedisCallback<Long>() {                public Long doInRedis(RedisConnection connection) throws DataAccessException {                    long result = 0;                    for (int i = 0; i < keys.length; i++) {                        result = connection.del(keys[i].getBytes());                        result++;                    }                    return result;                }            });            return re;        } catch (Exception e) {            return null;        }    }    /**     * @param key     * @param value     * @param liveTime     */    public void set(final byte[] key, final byte[] value, final long liveTime) {        if (!isUse)            return;        try {            redisTemplate.execute(new RedisCallback<Long>() {                public Long doInRedis(RedisConnection connection) throws DataAccessException {                    connection.set(key, value);                    if (liveTime > 0) {                        connection.expire(key, liveTime);                    }                    return 1L;                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();        }    }    /**     * @param key     * @param value     * @param liveTime     */    public void set(String key, String value, long liveTime) {        this.set(getBytes(key), getBytes(value), liveTime);    }    /**     * @param key     * @param liveTime     */    public boolean expire(String key, long liveTime) {        if (!isUse)            return false;        try {            return redisTemplate.execute(new RedisCallback<Boolean>() {                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {                    return connection.expire(key.getBytes(), liveTime);                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return false;        }    }    /**     * @param key     * @param value     */    public void set(String key, String value) {        this.set(key, value, 0L);    }    /**     * @param key     * @param value     */    public void set(byte[] key, byte[] value) {        this.set(key, value, 0L);    }    /**     * @param key     * @param value     */    public void set(String key, byte[] value) {        this.set(getBytes(key), value, 0L);    }    /**     *      */    @Override    public void setOjb(String key, Object value, long time) {        this.set(getBytes(key), getBytes(JSON.toJSONString(value)), time);    }    /**     * @param key     * @return     */    public String get(final String key) {        if (!isUse)            return null;        try {            return redisTemplate.execute(new RedisCallback<String>() {                public String doInRedis(RedisConnection connection) throws DataAccessException {                    try {                        byte[] bytes = connection.get(getBytes(key));                        if (bytes == null || bytes.length == 0) {                            return null;                        }                        return new String(bytes, redisCode);                    } catch (UnsupportedEncodingException e) {                        e.printStackTrace();                    } catch (Exception e1) {                        e1.printStackTrace();                        return null;                    }                    return "";                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return null;        }    }    public byte[] get4byte(final String key) {        if (!isUse)            return null;        try {            return redisTemplate.execute(new RedisCallback<byte[]>() {                public byte[] doInRedis(RedisConnection connection) throws DataAccessException {                    try {                        return connection.get(getBytes(key));                    } catch (Exception e1) {                        e1.printStackTrace();                        return null;                    }                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return null;        }    }    @Override    public <T> T getObj(String key, Class<T> elementType) {        String jsonString = this.get(key);        T obj;        obj = JSON.parseObject(jsonString, elementType);        if (obj == null) {            try {                obj = elementType.newInstance();// 防止空指针异常            } catch (InstantiationException | IllegalAccessException e) {                throw new CommonException("get redis error:", e);            }        }        return obj;    }    /**     * @param pattern     * @return     */    public void Setkeys(String pattern) {        if (!isUse)            return;        try {            redisTemplate.keys(pattern);        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();        }    }    /**     * @param key     * @return     */    public boolean exists(final String key) {        if (!isUse)            return false;        try {            return redisTemplate.execute(new RedisCallback<Boolean>() {                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {                    return connection.exists(getBytes(key));                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return false;        }    }    /**     * @return     */    // public String flushDB() {    // if(!isUse) return null;    // return redisTemplate.execute(new RedisCallback<String>() {    // public String doInRedis(RedisConnection connection) throws    // DataAccessException {    // connection.flushDb();    // return "ok";    // }    // });    // }    public boolean flushDB() {        if (!isUse)            return false;        try {            return redisTemplate.execute(new RedisCallback<Boolean>() {                public Boolean doInRedis(RedisConnection connection) throws DataAccessException {                    connection.flushDb();                    return true;                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return false;        }    }    /**     * @return     */    public long dbSize() {        if (!isUse)            return 0;        try {            return redisTemplate.execute(new RedisCallback<Long>() {                public Long doInRedis(RedisConnection connection) throws DataAccessException {                    return connection.dbSize();                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return 0;        }    }    /**     * @return     */    public String ping() {        if (!isUse)            return null;        try {            return redisTemplate.execute(new RedisCallback<String>() {                public String doInRedis(RedisConnection connection) throws DataAccessException {                    return connection.ping();                }            });        } catch (Exception e) {            closeSwitch(e);            e.printStackTrace();            return null;        }    }    private void closeSwitch(Exception e) {        if (e instanceof RedisConnectionFailureException) {            this.isUse = false;        }    }    /**     * submit check token     *      * @param token     * @return     */    public boolean checkToken(String token) {        if (StringUtils.isBlank(token)) {            return false;        }        Object tk = this.get(token);        if (tk != null) {            this.del(token);            return true;        }        return false;    }    @Override    public void setHm(String key, Map<String, String> map, long liveTime) {        if (!isUse)            return;        final Map<byte[], byte[]> hashes = new LinkedHashMap<byte[], byte[]>(map.size());        for (Map.Entry<String, String> entry : map.entrySet()) {            hashes.put(getBytes(entry.getKey()), getBytes(entry.getValue()));        }        redisTemplate.execute(new RedisCallback<Object>() {            public Object doInRedis(RedisConnection connection) {                connection.hMSet(getBytes(key), hashes);                if (liveTime > 0) {                    connection.expire(getBytes(key), liveTime);                }                return null;            }        }, true);    }    @Override    public Map<String, String> getHm(String key) {        final byte[] rawKey = getBytes(key);        Map<byte[], byte[]> entries = redisTemplate.execute(new RedisCallback<Map<byte[], byte[]>>() {            public Map<byte[], byte[]> doInRedis(RedisConnection connection) {                return connection.hGetAll(rawKey);            }        }, true);        Map<String, String> map = new LinkedHashMap<String, String>(entries.size());        for (Map.Entry<byte[], byte[]> entry : entries.entrySet()) {            try {                map.put(new String(entry.getKey(), redisCode), new String(entry.getValue(), redisCode));            } catch (UnsupportedEncodingException e) {                return new HashMap<String, String>();            }        }        return map;    }    @Override    public void setList(String key, List<String> list, long liveTime) {        if (!isUse)            return;        final List<byte[]> listes = new ArrayList<byte[]>(list.size());        for (String value : list) {            listes.add(getBytes(value));        }        redisTemplate.execute(new RedisCallback<Object>() {            public Object doInRedis(RedisConnection connection) {                for (byte[] bs : listes) {                    connection.rPush(getBytes(key), bs);                }                if (liveTime > 0) {                    connection.expire(getBytes(key), liveTime);                }                return null;            }        }, true);    }    @Override    public List<String> getList(String key) {        final byte[] rawKey = getBytes(key);        List<byte[]> entries = redisTemplate.execute(new RedisCallback<List<byte[]>>() {            public List<byte[]> doInRedis(RedisConnection connection) {                return connection.lRange(rawKey, 0, -1);            }        }, true);        List<String> list = new ArrayList<String>(entries.size());        for (byte[] entry : entries) {            try {                list.add(new String(entry, redisCode));            } catch (UnsupportedEncodingException e) {                return new ArrayList<String>();            }        }        return list;    }}

接口: RedisSpringService.java

package com.maigangle.b2b.common.redis;import java.util.List;import java.util.Map;/** * redis对外提供服务接口,如需使用请先注入(基于spring) *  * @author 朱晗 * @since 2016年11月28日 上午8:41:45 * @version 1.0 * */public interface RedisSpringService {    /**     * 发布消息     *      */    public abstract void pub(String channel, String param);    /**     * 通过key删除     *      * @param key     */    public abstract Long del(String... keys);    /**     * 添加key value 并且设置存活时间(byte)     *      * @param key     * @param value     * @param liveTime     */    public abstract void set(byte[] key, byte[] value, long liveTime);    /**     * 添加key value 并且设置存活时间     *      * @param key     * @param value     * @param liveTime     *            单位秒     */    public abstract void set(String key, String value, long liveTime);    /**     * 设置key过期时间     *      * @param key     * @param liveTime     * @return     */    public abstract boolean expire(String key, long liveTime);    /**     * 添加key value     *      * @param key     * @param value     */    public abstract void set(String key, String value);    /**     * 添加key value     *      * @param key     * @param value     */    public abstract void set(String key, byte[] value);    /**     * 添加key value (字节)(序列化)     *      * @param key     * @param value     */    public abstract void set(byte[] key, byte[] value);    /**     * 保存对象     *      * @param key     * @param value     */    public abstract void setOjb(final String key, Object value, long time);    /**     * 获取redis value (String)     *      * @param key     * @return     */    public abstract String get(String key);    public abstract byte[] get4byte(String key);    /**     * 得到对象     *      * @param key     * @param elementType     * @return     */    public abstract <T> T getObj(final String key, Class<T> elementType);    /**     * 通过正则匹配keys     *      * @param pattern     * @return     */    public abstract void Setkeys(String pattern);    /**     * 检查key是否已经存在     *      * @param key     * @return     */    public abstract boolean exists(String key);    /**     * 清空redis 所有数据     *      * @return     */    // public abstract String flushDB();    public abstract boolean flushDB();    /**     * 查看redis里有多少数据     */    public abstract long dbSize();    /**     * 检查是否连接成功     *      * @return     */    public abstract String ping();    /**     * submit check token     *      * @param token     * @return     */    public boolean checkToken(String token);    /**     *      * @author 朱晗     * @since 2017年6月7日 上午8:45:55     * @param key     * @param map     * @param liveTime     */    public void setHm(String key, Map<String, String> map, long liveTime);    /**     *      * @author 朱晗     * @since 2017年6月7日 上午8:45:58     * @param key     * @return     */    public Map<String, String> getHm(String key);    /**     *      * @author 朱晗     * @since 2017年6月7日 上午8:46:50     * @param key     * @param list     * @param liveTime     */    public void setList(String key, List<String> list, long liveTime);    /**     *      * @author 朱晗     * @since 2017年6月7日 上午8:46:55     * @param key     * @return     */    public List<String> getList(String key);}

前端:

login.js

$('#loginIn').click(function(event) {         var $this = $(this);        var acc = $('#account').val();        var pw = $('#password').val();        var loadUrl = util.get('redirectURL');        var loginValid = $("#loginForm").valid();        var setHtml = '';        var loginUrl = '';        // 如果返回false 设置为空        if (loadUrl === false) {            loadUrl = '';        }        if(loginValid) {            $this.text('正在登录...');            $this.attr('disabled', true);            $.ajax({                url: apiPath + '/auth/ajaxDoLogin',                type: 'post',                data: {                    account: acc,                    passwd: pw,                    redirectURL: loadUrl                },                success: function(data) {                    if (data.isVaild) {                        if(data.role === 'A'){                            setHtml += '<iframe src="' + gangUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_ +'"></iframe>';                            setHtml += '<iframe src="' + payUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + orderUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + homeUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + cartUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + cangkuUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + fundUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + regUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + baikeUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + helpUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                            setHtml += '<iframe src="' + indexUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                        }else if(data.role === 'B'){                             setHtml += '<iframe src="' + cangkuUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                        }else if(data.role === 'C'){                             setHtml += '<iframe src="' + mcUrlBase + '/api/common/setCookie?_it_=' + data._it_ + '&_token_='+ data._token_  + '"></iframe>';                        }                        if(data.isNotBindPhone) {                            window.location.href = data.redirectURL + '?firmId=' + data.firmId;                        } else {                            // 添加iframe执行写入cookie                            $('#setCookieView').html(setHtml);                            setTimeout(function() {                               window.location.href = data.redirectURL;                            }, 2000);                        }                    } else {                        $('#accError').show();                        $('#accError').text(data.msg);                        $this.text('我同意交易规则,登录');                        $this.attr('disabled', false);                    }                },                error: function(msg){                    $('#accError').show();                    $('#accError').text('登录失败!');                    $this.text('我同意交易规则,登录');                    $this.attr('disabled', false);                }            });        }    });

后端java代码

@RequestMapping(value = "/ajaxDoLogin")    @ResponseBody    public Map<String, Object> ajaxDoLogin( HttpServletRequest request,                                            HttpServletResponse response,                                            String account,                                            String passwd,                                            String redirectURL) {        String logBatch = LogBatchUtil.getLogUUID(EnumMonitorLog.LOGSYSTEM_LOGIN.getKey());        Map<String, Object> resultMap = new HashMap<String, Object>();        try {            super.logInfo(  request,                            logBatch,                            "登录",                            "进入登录相关数据,account:" + account + ",redirectURL:" + redirectURL,                            EnumMonitorLog.LOGSYSTEM_LOGIN.getKey());            account = account.replaceAll(" ", "");            // 登录验证            Map<String, Object> vaildMap = validateLogin(request, account, passwd);            boolean isVaild = (boolean) vaildMap.get("isVaild");            if (!isVaild) {                return vaildMap;            }            // 手机登录/交易商登录            if (loginService.countByMobile(account) == 0) {                resultMap = firmIdLogin(request, response, logBatch, account, passwd, redirectURL);// 账号为交易号            } else {                resultMap = mobileLogin(request, response, logBatch, account, passwd, redirectURL);// 账号为手机号码            }            return resultMap;        }        catch (Exception e) {            e.printStackTrace();            super.logError( request,                            logBatch,                            "账号为:" + account + "会员登录失败",                            "交易商ID为:" + getFirmId(request) + "错误信息为:" + ExceptionUtils.getStackTrace(e),                            Boolean.getBoolean(redisSpringService.get(EnumMonitorLog.LOG_NOTIFY_SWITCH.getKey())),                            EnumMonitorLog.LOGSYSTEM_LOGIN.getKey());            resultMap.put("msg", "非法登录");            resultMap.put("isVaild", false);            return resultMap;        }    }private Map<String, Object> firmIdLogin(HttpServletRequest request,                                            HttpServletResponse response,                                            String logBatch,                                            String account,                                            String passwd,                                            String redirectURL) {        AcntUserBasic acntUserBasic = null;        Map<String, Object> resultMap = null;        // 账号为交易号        if (!loginApi(request, logBatch, account, passwd)) {            return this.setLoginError(account, passwd);        }        acntUserBasic = loginService.selectByFirmId(account);        if (acntUserBasic != null && !StringUtils.equals(acntUserBasic.getIsLock(), IsLockEnum.IS_LOCK_N.getKey())) {            return this.setLockError(account, passwd, "登录帐号" + account + IsLockEnum.getLockInfo(acntUserBasic.getIsLock()));        }        // 用户基本信息不存在或手机号为空(后台新增用户)        if (acntUserBasic == null || StringUtils.isBlank(acntUserBasic.getMobile())) {            // 绑定手机号            resultMap = new HashMap<String, Object>();            resultMap.put("isVaild", true);            resultMap.put("isNotBindPhone", true);            resultMap.put("redirectURL", super.getUrl(AuthUrlConstant.LOGIN_URL) + "/auth/bindPhoneFirst");            resultMap.put("firmId", account);            return resultMap;        }        super.logInfo(request, logBatch, "会员登录", "通过pc端进行登录认证," + "账号为:" + account + "会员认证成功", EnumMonitorLog.LOGSYSTEM_LOGIN.getKey());        String token = UUIDUtil.getRandomUUID();// 登录token        setLoginInfo(request, response, acntUserBasic, logBatch, account, token);        resultMap = redirectToURL(acntUserBasic.getUserId(), acntUserBasic.getUserRole(), redirectURL, token);        resultMap.put("role", acntUserBasic.getUserRole());//返回用户角色        return resultMap;    }private void setLoginInfo(  HttpServletRequest request,                                HttpServletResponse response,                                AcntUserBasic acntUserBasic,                                String logBatch,                                String account,                                String token) {        super.logInfo(request, logBatch, "模拟session", "通过pc端进行登录,开始模拟session" + "账号为:" + account, EnumMonitorLog.LOGSYSTEM_LOGIN.getKey());        String apiToken = UUIDUtil.getRandomUUID();        List<String> dptIds = null;        // 用户权限为仓管时查询该用户的仓库        if (StringUtils.equals(acntUserBasic.getUserRole(), USER_ROLE_B)) {            List<AcntDepotRel> acntDepotRels = loginService.findAcntDepotRelsByFirmId(acntUserBasic.getFirmId());            if (acntDepotRels != null && acntDepotRels.size() > 0) {                dptIds = new ArrayList<String>();                for (AcntDepotRel acntDepotRel : acntDepotRels) {                    dptIds.add(acntDepotRel.getDptId());                }            }        }        String isCert = acntUserBasic.getIsCert();        if (StringUtils.equals(isCert, YesOrNoEnum.NO.getKey())) {            AcntUserCert acntUserCert = new AcntUserCert();            acntUserCert.setUserId(acntUserBasic.getUserId());            if (loginService.countAcntUserCert(acntUserCert) == 0) {                isCert = CertStatusEnum.CERTSTATUS_S.getKey();// 没有认证                if (loginService.countAcntUserCertFail(acntUserCert) > 0) {                    isCert = CertStatusEnum.CERTSTATUS_X.getKey();// 认证不通过                }            } else {                acntUserCert = loginService.getOneAcntUserCert(acntUserCert);                isCert = acntUserCert.getCertStatus();            }        }        AcntUserMall acntUserMall = loginService.selectAcntUserMallByFirmId(acntUserBasic.getFirmId());        String company = "";        if (acntUserMall != null) {            company = acntUserMall.getCompany();        }        // 模拟session登录成功        setSimulateSession( request,                            acntUserBasic.getUserId(),                            acntUserBasic.getMobile(),                            acntUserBasic.getFirmId(),                            acntUserBasic.getUserType(),                            acntUserBasic.getUserRole(),                            company,                            isCert,                            dptIds,                            loginService.selectPrivCodeByFirmId(acntUserBasic.getFirmId()),                            apiToken,                            token);        // 设置cookie        CookieUtils.setCookie(request, response, CookieConstant.PUT_USERID_NAME, EncryptUtils.encrypt(acntUserBasic.getUserId()), 0);        // 设置登录token        CookieUtils.setCookie(request, response, CookieConstant.PUT_TOKEN_INFO, token, 0);        loginService.insertAcntUserLogin(IpUtil.getIpAddr(request), acntUserBasic.getUserId(), acntUserBasic.getUserRole());        // 插入uvId userId关系        RequestUvUserRel requestUvUserRel = new RequestUvUserRel();        requestUvUserRel.setUserId(acntUserBasic.getUserId());        requestUvUserRel.setUvId(CookieUtils.getCookieValue(request, CookieConstant.UV_ID));        requestUvUserRel.setCreateTime(MongoDateUtil.getMongoDate(new Date()));        loginService.insertRequestUvUserRel(requestUvUserRel);        super.logInfo(request, logBatch, "模拟session", "通过pc端进行登录,模拟session成功" + "账号为:" + account, EnumMonitorLog.LOGSYSTEM_LOGIN.getKey());    }protected void setSimulateSession(  HttpServletRequest request,                                        String userId,                                        String mobile,                                        String firmId,                                        String userType,                                        String userRole,                                        String company,                                        String isCert,                                        List<String> dptIds,                                        List<String> privCodes,                                        String apiToken,                                        String token) {        SessionInfo sessionInfo = new SessionInfo();        sessionInfo.setMobile(mobile);        sessionInfo.setFirmId(firmId);        sessionInfo.setUserType(userType);        sessionInfo.setUserRole(userRole);        sessionInfo.setCompanyName(company);        sessionInfo.setLoginIp(IpUtil.getIpAddr(request));        sessionInfo.setUserId(userId);        sessionInfo.setIsCert(isCert);        sessionInfo.setApiToken(apiToken);        sessionInfo.setDptIds(dptIds);        sessionInfo.setPrivCodes(privCodes);        sessionInfo.setToken(token);        // 存放登录信息        redisService.setOjb(SessionConstant.SIMULATE_SESSION_NAME + userId, sessionInfo, 1800);        // 设置apiToken时间为8小时        redisService.set(apiToken, "", 8 * 3600);// 默认8个小时    }

页面拦截器:

<mvc:interceptors>        <!-- 登录认证 -->        <mvc:interceptor>            <mvc:mapping path="/rollGangPay/**" />            <mvc:mapping path="/rollImport/**" />            <mvc:mapping path="/rollManage/**" />            <mvc:mapping path="/rollPublish/**" />            <mvc:mapping path="/flatImport/**" />            <mvc:mapping path="/flatManage/**" />            <mvc:mapping path="/flatPriceModal/**" />            <!-- 需排除拦截的地址 -->            <mvc:exclude-mapping path="/rollImport/uploadWare" />            <mvc:exclude-mapping path="/rollImport/importBendingWare" />            <mvc:exclude-mapping path="/flatImport/uploadWare" />            <mvc:exclude-mapping path="/flatImport/importBendingWare" />            <mvc:exclude-mapping path="/flatImport/stayPublishWare" />            <bean class="com.maigangle.b2b.common.web.interceptor.AuthLoginInterceptor"></bean>        </mvc:interceptor>    </mvc:interceptors>

拦截器类:AuthLoginInterceptor.java

package com.maigangle.b2b.common.web.interceptor;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.StringUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import com.maigangle.b2b.common.base.SessionInfo;import com.maigangle.b2b.common.enums.CertStatusEnum;import com.maigangle.b2b.common.enums.UserRoleEnum;import com.maigangle.b2b.common.enums.YesOrNoEnum;import com.maigangle.b2b.common.redis.RedisSpringService;import com.maigangle.b2b.common.util.EncryptUtils;import com.maigangle.b2b.common.web.constants.AuthUrlConstant;import com.maigangle.b2b.common.web.constants.CookieConstant;import com.maigangle.b2b.common.web.constants.SessionConstant;import com.maigangle.b2b.common.web.util.CookieUtils;/** * 会员已经认证登录拦截(此文件请不要修改,如需修改请找相应的负责人) 后期要进行拆分保持功能解耦度更低 *  * @author 朱晗 * @since 2016年11月28日 下午12:36:49 * @version 1.0 * */@Repositorypublic class AuthLoginInterceptor extends HandlerInterceptorAdapter {    @Autowired    RedisSpringService redisSpringService;    private static final String HEADER = "x-requested-with";    private static final String XML_HTTP_REQUEST = "XMLHttpRequest";    private String isReferer = YesOrNoEnum.NO.getKey();// 是否referer跳转    private Map<String, String> excludedUrls;// 指定拦击地址到指定路径    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        // 判断userId是否为空        String userId = CookieUtils.getCookieValue(request, CookieConstant.PUT_USERID_NAME);        System.out.println("userId:" + userId);        if (StringUtils.isBlank(userId)) {            return judgeAjaxJumpLogin(request, response);        }        // 判断userId是为正确的        userId = EncryptUtils.decrypt(userId);        System.out.println("userId:" + userId);        if (StringUtils.isBlank(userId)) {            return judgeAjaxJumpLogin(request, response);        }        // 判断用户是否已登录        boolean existLogin = redisSpringService.exists(SessionConstant.SIMULATE_SESSION_NAME + userId);        System.out.println("existLogin:" + existLogin);        if (!existLogin) {            return judgeAjaxJumpLogin(request, response);        }        // 判断用户是否已认证        SessionInfo sessionInfo = redisSpringService.getObj(SessionConstant.SIMULATE_SESSION_NAME + userId, SessionInfo.class);        String isCert = sessionInfo.getIsCert();        if (!StringUtils.equals(isCert, CertStatusEnum.CERTSTATUS_Y.getKey())) {            if (StringUtils.equals(isCert, CertStatusEnum.CERTSTATUS_N.getKey())) {                // 认证中                return judgeAjaxJumpAuthIn(request, response);            } else if (StringUtils.equals(isCert, CertStatusEnum.CERTSTATUS_X.getKey())) {                // 认证不通过                return judgeAjaxJumpAuthNoPass(request, response);            } else if (StringUtils.equals(isCert, CertStatusEnum.CERTSTATUS_S.getKey())) {                // 没有认证                return judgeAjaxJumpAuthNo(request, response);            }        }        // 判断是否有相应的商城交易权限        if (!StringUtils.equals(sessionInfo.getUserRole(), UserRoleEnum.DEALER.getKey())) {            return judgeAjaxJumpRole(request, response);        }        // 判断网路环境是否变化        /*         * String requestiIp = IpUtil.getIpAddr(request);         * System.out.println("requestiIp:"+requestiIp); String loginIp =         * redisSpringService.getObj(SessionConstant.SIMULATE_SESSION_NAME +         * userId, SessionInfo.class).getLoginIp();         * System.out.println("loginIp:"+loginIp); if         * (!requestiIp.equals(loginIp)) { return judgeAjaxJumpLogin(request,         * response); }         */        redisSpringService.expire(SessionConstant.SIMULATE_SESSION_NAME + userId, 1800);        return true;    }    @Override    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {}    @Override    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {}    private boolean judgeAjaxJumpLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {        if (StringUtils.equals(isReferer, YesOrNoEnum.NO.getKey())) {            if (request.getHeader(HEADER) != null && request.getHeader(HEADER).equalsIgnoreCase(XML_HTTP_REQUEST)) {                response.setHeader("sessionstatus", "interceptorErrpr"); // 响应头设置session状态                response.setHeader("redirectURL", getReferLoginUrl(request));                return false;            } else {                response.sendRedirect(getRequestLoginUrl(request));                return false;            }        } else {            String b2bLoginUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);            String redirectURL = request.getHeader("referer");            // 获取referer是否为空,空直接跳转到登录界面            if (StringUtils.isNotBlank(redirectURL)) {                if (excludedUrls != null && !excludedUrls.isEmpty()) {                    for (String key : excludedUrls.keySet()) {                        if (redirectURL.contains(key)) {                            redirectURL = redirectURL.replace(key, excludedUrls.get(key));                            break;                        }                    }                }                String decodeUrl = URLEncoder.encode(redirectURL, "UTF-8");                String url = b2bLoginUrl + "?redirectURL=" + decodeUrl;                if (request.getHeader(HEADER) != null && request.getHeader(HEADER).equalsIgnoreCase(XML_HTTP_REQUEST)) {                    response.setHeader("sessionstatus", "interceptorErrpr"); // 响应头设置session状态                    response.setHeader("redirectURL", url);                    return false;                } else {                    response.sendRedirect(url);                    return false;                }            } else {                response.sendRedirect(getRequestLoginUrl(request));                return false;            }        }    }    /**     * 没有认证     *      * @author 王振光     * @since 2017年6月14日 上午11:07:40     * @param request     * @param response     * @return     * @throws IOException     */    private boolean judgeAjaxJumpAuthNo(HttpServletRequest request, HttpServletResponse response) throws IOException {        String b2bAuthUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);        String redirectUrl = b2bAuthUrl + "/userAuth/noAuth";        if (request.getHeader(HEADER) != null && request.getHeader(HEADER).equalsIgnoreCase(XML_HTTP_REQUEST)) {            response.setHeader("sessionstatus", "interceptorErrpr"); // 响应头设置session状态            response.setHeader("redirectURL", redirectUrl);            return false;        } else {            response.sendRedirect(redirectUrl);            return false;        }    }    /**     * 认证中     *      * @author 王振光     * @since 2017年6月14日 上午11:07:19     * @param request     * @param response     * @return     * @throws IOException     */    private boolean judgeAjaxJumpAuthIn(HttpServletRequest request, HttpServletResponse response) throws IOException {        String b2bAuthUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);        String redirectUrl = b2bAuthUrl + "/userAuth/inAuth";        if (request.getHeader(HEADER) != null && request.getHeader(HEADER).equalsIgnoreCase(XML_HTTP_REQUEST)) {            response.setHeader("sessionstatus", "interceptorErrpr"); // 响应头设置session状态            response.setHeader("redirectURL", redirectUrl);            return false;        } else {            response.sendRedirect(redirectUrl);            return false;        }    }    /**     * 认证不通过     *      * @author 王振光     * @since 2017年6月14日 上午11:07:49     * @param request     * @param response     * @return     * @throws IOException     */    private boolean judgeAjaxJumpAuthNoPass(HttpServletRequest request, HttpServletResponse response) throws IOException {        String b2bAuthUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);        String redirectUrl = b2bAuthUrl + "/userAuth/noPassAuth";        if (request.getHeader(HEADER) != null && request.getHeader(HEADER).equalsIgnoreCase(XML_HTTP_REQUEST)) {            response.setHeader("sessionstatus", "interceptorErrpr"); // 响应头设置session状态            response.setHeader("redirectURL", redirectUrl);            return false;        } else {            response.sendRedirect(redirectUrl);            return false;        }    }    /**     * 角色错误提示<br>     *      * @author 王振光     * @since 2017年8月8日 上午9:51:31     * @param request     * @param response     * @return     * @throws IOException     */    private boolean judgeAjaxJumpRole(HttpServletRequest request, HttpServletResponse response) throws IOException {        String b2bAuthUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);        String redirectUrl = b2bAuthUrl + "/system/roleErr";        if (request.getHeader(HEADER) != null && request.getHeader(HEADER).equalsIgnoreCase(XML_HTTP_REQUEST)) {            response.setHeader("sessionstatus", "interceptorErrpr"); // 响应头设置session状态            response.setHeader("redirectURL", redirectUrl);            return false;        } else {            response.sendRedirect(redirectUrl);            return false;        }    }    private String getRequestLoginUrl(HttpServletRequest request) throws UnsupportedEncodingException {        String b2bLoginUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);        String redirectURL = request.getRequestURL().toString();        String query = request.getQueryString();        if (StringUtils.isNotBlank(query)) {            redirectURL = redirectURL + "?" + query;        }        String decodeUrl = URLEncoder.encode(redirectURL, "UTF-8");        return b2bLoginUrl + "?redirectURL=" + decodeUrl;    }    private String getReferLoginUrl(HttpServletRequest request) throws UnsupportedEncodingException {        String b2bLoginUrl = redisSpringService.getHm(AuthUrlConstant.B2B_AUTH_URL).get(AuthUrlConstant.LOGIN_URL);        String redirectURL = request.getHeader("referer");        String decodeUrl = URLEncoder.encode(redirectURL, "UTF-8");        return b2bLoginUrl + "?redirectURL=" + decodeUrl;    }    public String getIsReferer() {        return isReferer;    }    public void setIsReferer(String isReferer) {        this.isReferer = isReferer;    }    public Map<String, String> getExcludedUrls() {        return excludedUrls;    }    public void setExcludedUrls(Map<String, String> excludedUrls) {        this.excludedUrls = excludedUrls;    }}
阅读全文
0 0
原创粉丝点击