关于SSO系统登出逻辑的分析:
1.用户登陆后产生token并写入cookie,跳转portal首页后从cookie中取token,进行用户身份核查。
2.用户点击退出按钮后,应请求登出这一业务逻辑。即:删除token所包含的在Redis中的用户信息。
3.删除Redis缓存的用户信息后,进行页面重置操作。即刷新页面操作。
废话不多说,直接上代码:
Service层接口实现类:
/*
* 用户登出
* */
@Override
public TaotaoResult logout(String token) {
//根据token获取用户信息
String json = jedisClient.get(REDIS_SESSION_TOKEN_KEY + ":" + token);
//判断缓存中是否用户信息 -- 因为设立了过期时间
if(StringUtils.isBlank(json)) {
return TaotaoResult.ok();
}else {
//若缓存仍存在,进行缓存的删除
jedisClient.del(REDIS_SESSION_TOKEN_KEY + ":" + token);
}
return TaotaoResult.ok();
}
首先根据token在Redis缓存中获取用户信息,之后对token信息进行判空处理,若不存在直接返回结果,若存在则删除缓存。
Controller层:
/*
* 用户登出
* */
@RequestMapping("/user/logout/{token}")
@ResponseBody
public Object logout(@PathVariable String token,String callback){
try {
TaotaoResult result = loginService.logout(token);
//这里采用了MappingJacksonValue解决jsonp跨域调用问题 springMVC 4.1+
if (StringUtils.isNotBlank(callback)) {
//创建MappingJacksonValue对象进行result对象包装
MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
//配置回调函数名
mappingJacksonValue.setJsonpFunction(callback);
return mappingJacksonValue;
}
return result;
} catch (Exception e) {
e.printStackTrace();
return TaotaoResult.build(500,ExceptionUtil.getStackTrace(e));
}
}
重点来了,前端时怎样进行发送请求的?
这里对js文件进行了改造
1.退出的<a>标签元素 -- 设立id属性,为了绑定jq选择器,发送ajax请求。
var html = username + ",欢迎来到淘淘!<a class=\"link-logout\" id='logout'>[退出]</a>";
2.采用jq选择器,进行ajax请求构建
//登出发送ajax请求
$("#logout").click(function () {
$.ajax({
url : "http://localhost:8084/user/logout/" + _ticket,
dataType : "jsonp",
type : "GET",
error: function(request) { //失败
alert("登出失败!");
},
success: function(data) { //成功
if (data.status == 200){
alert("登出成功!");
window.location.href="http://localhost:8082"
}
}
});
});
测试:
用户登录:
查看缓存:已生成对应的token。
用户退出
此时刷新当前页面,查看缓存:已清除。