转发请注明出处
sso的一种常用做法是,设置一个顶层一级域名(比如:.baidu.com), 这样其他二级域名,如wenku.baidu.com, pan.baidu.com就能在当前域名的服务节点获取其他二级域名设置的cookie, 进而实现sso单点登录功能
以下是详细步骤
- 通过域名获取一级domain LoginController.java
//成员变量
private String reg = "(\\w*\\.?){1,2}\\.(com.cn|net.cn|gov.cn|org\\.nz|org.cn|com|net|org|gov|cc|biz|info|cn|co)$";
private Pattern pattern = Pattern.compile(reg);
/**
* 获取当前请求网站的一级域名
* @param fullDomain 如:pan.baidu.com
* @return 返回cookie需要的一级domain 如:.baidu.com
*/
private String getDynamicCookieDomain(String fullDomain) {
if(StringUtils.isEmpty(fullDomain)) {
return Strings.EMPTY;
}
Matcher matcher = pattern.matcher(fullDomain);
final List<String> domain = new ArrayList<>();
if(matcher.find()) {
IntStream.rangeClosed(1, matcher.groupCount()).forEach(i ->
domain.add("." + matcher.group(i))
);
}
return String.join("", domain);
}
- 增加设置cookie的方法 LoginController.java
/**
* 登录时设置sso的cookie
* @param request
* @param response
* @param token
* @param maxAge 单位:秒
*/
private void setCookies(HttpServletRequest request, HttpServletResponse response, String token, Long maxAge) {
String cookieFormat = "token=%s; Path=/;Domain=%s;Max-Age=%s;";
String cookieValue = String.format(cookieFormat, token, getDynamicCookieDomain(request.getHeader("x-forwarded-host")), maxAge);
log.info("set cookie value: {}", cookieValue);
response.setHeader("Set-Cookie", cookieValue);
}
- 登录成功后调用setCookies方法在响应中输出cookie LoginController.java
@Value("${sso.cookie.maxAge}")
private Long cookieMaxAge;
/**
* 登录
* @param request
* @param response
* @return
* @throws Exception
*/
@RequestMapping(value="/login")
public @ResponseBody ResultEntity<Object> login(HttpServletRequest request, HttpServletResponse response, LoginVo loginVo, String deviceId) throws Exception {
ResultEntity<Object> result = new ResultEntity<Object>();
//...省略业务代码
JSONObject jsonObject = ResultEntityHelper.getData(resultEntity, JSONObject.class);
String token = jsonObject.getString("token");
Map<String,Object> data = new HashMap<>();
data.put("userKey", token);
setCookies(request, response, token, cookieMaxAge);
return result.data(data);
}
- 退出时设置cookie过期 LoginController.java
/**
* 退出
* @param request
* @param response
* @return
*/
@RequestMapping(value="/signOut")
public @ResponseBody ResultEntity<Object> signOut(HttpServletRequest request, HttpServletResponse response) throws Exception {
//创建返回结果
ResultEntity<Object> result = new ResultEntity<Object>();
//... 省略退出逻辑
setCookies(request, response, LoginInfoHolder.token(), 0L);
return result;
}
-附加:相关参数在yml中配置 application.yml 及cookie在浏览器的呈现
#配置sso的cookie过期时间,单位:秒
sso:
cookie:
maxAge: 3600
百度cookie截图.png
联系作者:do_believe@163.com