单点登录系统思路
传统方法cookie加session在基于分布式架构的高并发项目已经不能满足. (session复制会限制tomcat的数量不能太多)
解决思路:
多个tomcat同时且只提供服务,那么可以用UUID生成一串字符串再用MD5加密(token)来模拟session,存到Redis集群并设置过期时间.再将token存到cookie发给用户.当需要查询用户登录状态时,再用这串token到Redis查询.有则重新设置过期时间.
其他业务逻辑雷同.
新学到的技术点 jsonp
问题来源:js不能跨域请求,所以当商城首页(端口8082)跨域请求sso系统(端口8088)时,request相应200,但response没有内容,且报错:什么什么是不被允许的.
解决方法:利用js可以跨域请求js的特性(请求到的js会立即执行)绕开这个问题.
前端自定义一个callback函数(jquery在ajax请求中加入datatype:jsonp jquery会自动写一个callback函数并在请求参数中添加参数callback=xxxx)
后端:
方法1:思路返回值变成 回调函数名+(+json+);
//查询登录状态
@RequestMapping(value="/user/token/{token}",method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String getUserLoginStatus(@PathVariable String token,String callback){
TaotaoResult userResult = userService.getUSerByToken(token);
if(StringUtils.isNotBlank(callback)){
return callback+"("+JsonUtils.objectToJson(userResult)+")";
}
return JsonUtils.objectToJson(userResult);
}
方法2:mappingJacksonValue
@RequestMapping(value="/user/token/{token}",method=RequestMethod.GET)
@ResponseBody
public Object getUserLoginStatus(@PathVariable String token,String callback){
TaotaoResult userResult = userService.getUSerByToken(token);
if(StringUtils.isNotBlank(callback)){
MappingJacksonValue mappingJacksonValue=new MappingJacksonValue(userResult);
mappingJacksonValue.setJsonpFunction(callback);
return mappingJacksonValue;
}
return userResult;
}