基于Redis+Cookie实现Session共享

公众号上线啦!
搜一搜【国服冰】
使命:尽自己所能给自学后端开发的小伙伴提供一个少有弯路的平台
回复:国服冰,即可领取我为大家准备的资料,里面包含整体的Java学习路线,电子书,以及史上最全的面试题!

分布式项目中要实现单点登录(SSO - Single Sign On):对于同一个客户端(例如 Chrome 浏览器),只要登录了一个子站(例如 a.com),则所有子站(b.comc.com)都认为已经登录。
比如用户在登录淘宝后,跳转到天猫时就已经登录了。

通过redis缓存和cookie实现单点登录:
共享Session

登录接口逻辑处理:

    @ResponseBody
    @RequestMapping("/dologin")
    public Result<String> doLogin(String nickname,String password,HttpServletResponse response){
        User loginUser = userDao.selectUserByNickName(nickname);
        if(loginUser == null){
            return Result.error(CodeMsg.NICKNAME_NOT_EXIST);
        }
        String salt = loginUser.getSalt();
        //将表单提交的密码二次md5
        String s = Md5Utils.formPassToDb(password, salt);
        //验证密码
        if(s.equals(loginUser.getPassword())){
            //生成随机的token
            String token = UUIDUtil.uuid();
            //将token和用户作为key与value存入缓存
            redisService.set(MiaoSha_UserKey.userKeyToken,token,loginUser);
            //封装cookie
            Cookie cookie = new Cookie(COOKIE_NAME,token);
            //设置cookie过期时间
            cookie.setMaxAge(MiaoSha_UserKey.userKeyToken.getExpireSeconds());
            cookie.setPath("/");
            response.addCookie(cookie);
            return Result.success(token);
        }
        return Result.error(CodeMsg.SERVER_ERROR);
    }

在其他接口中获取到登录用户,自定义一个参数解析器HandlerMethodArgumentResolver
在进行参数判断中可自定义一个注解,当某个参数被使用该注解后,则调用自定义的参数管理器

@Target(value = ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UserParameter {
}

HandlerMethodArgumentResolver :

@Component
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
    @Autowired
    private UserService userService;

    //先判断参数类型和是否贴了自定义注解,满足则进行下一步
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
       return parameter.getParameterType() == User.class && parameter.hasParameterAnnotation(UserParameter.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory){
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        Cookie[] cookies = request.getCookies();
        if(cookies == null || cookies.length <=0){
            return null;
        }
        String token = null;
        for(Cookie cookie : cookies){
            if(cookie.getName().equals(LoginController.COOKIE_NAME)){
                //拿到token
                token = cookie.getValue();
                break;
            }
        }
        User user = userService.getUserByToken(token);
        return user;
    }
}

遍历所有的cookie,直到找到登录时设置的 public static final String COOKIE_NAME = "token"; 获取该cookie的值(token)并查找redis拿到用户

将自定义解析器配置到springmvc管理:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    private UserArgumentResolver userArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(userArgumentResolver);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Redis作为JBoss的Session共享存储,需要配置以下步骤: 1. 首先,在JBoss服务器上安装Redis服务器和相关的Java Redis客户端 2. 在JBoss服务器的standalone.xml文件中添加以下配置: ``` <subsystem xmlns="urn:jboss:domain:infinispan:6.0" default-cache-container="web" jndi-name="infinispan"> <cache-container name="web" jndi-name="infinispan/web"> <transport lock-timeout="60000"/> <distributed-cache name="sessions" mode="SYNC" segmented="false"> <expiration max-idle="1800000"/> <persistence passivation="false"> <file-store path="${jboss.server.temp.dir}/infinispan/web/sessions" /> </persistence> <partition-handling when-split="MERGE" merge-policy="REMOVE_ALL" /> <file-store /> <remote-store> <property name="hotrod-client-properties" value="hotrod-client.properties"/> <property name="remote-cache-name" value="sessions"/> <property name="raw-values" value="false"/> <property name="shared" value="true"/> <property name="preload" value="true"/> </remote-store> </distributed-cache> </cache-container> </subsystem> ``` 3. 新建一个hotrod-client.properties文件,内容如下: ``` infinispan.client.hotrod.server_list=redis_host:redis_port ``` 其中,redis_host是Redis服务器的地址;redis_port是Redis服务器的端口号。 4. 将hotrod-client.properties文件放在JBoss服务器的classpath下。 5. 在Web应用程序的web.xml文件中添加以下配置: ``` <session-config> <session-store-name>infinispan</session-store-name> <cookie-config> <path>/</path> </cookie-config> </session-config> ``` 6. 重新启动JBoss服务器,即可使用Redis作为Session共享存储。 注意: 多个JBoss服务器之间通过Redis共享Session时,需要保证Redis使用的是同一个实例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值