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

登录接口逻辑处理:
@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();//将表单提交的密码二次md5String s = Md5Utils.formPassToDb(password, salt);//验证密码if(s.equals(loginUser.getPassword())){//生成随机的tokenString token = UUIDUtil.uuid();//将token和用户作为key与value存入缓存redisService.set(MiaoSha_UserKey.userKeyToken,token,loginUser);//封装cookieCookie 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)@Documentedpublic @interface UserParameter {}
HandlerMethodArgumentResolver :
@Componentpublic class UserArgumentResolver implements HandlerMethodArgumentResolver {@Autowiredprivate UserService userService;//先判断参数类型和是否贴了自定义注解,满足则进行下一步@Overridepublic boolean supportsParameter(MethodParameter parameter) {return parameter.getParameterType() == User.class && parameter.hasParameterAnnotation(UserParameter.class);}@Overridepublic 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)){//拿到tokentoken = cookie.getValue();break;}}User user = userService.getUserByToken(token);return user;}}
遍历所有的cookie,直到找到登录时设置的 public static final String COOKIE_NAME = "token"; 获取该cookie的值(token)并查找redis拿到用户
将自定义解析器配置到springmvc管理:
@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Autowiredprivate UserArgumentResolver userArgumentResolver;@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {resolvers.add(userArgumentResolver);}}







![[Error]在Swift项目Build Settings的Preprocessor Macros中定义的宏无效的问题](https://img-blog.csdnimg.cn/82261f16048145588f3c6d8e49f2e919.png#pic_left)











