做单点登录cookie无法写入的问题,虚拟机的nginx代理到win10的idea ,跨域
作为一个从不笔笔记的人,今天*记一个笔记
今天再学习springCloud +nginx 的时候做单点登陆,出现cookie无法写入问题
先交代一下环境
win10 idea
centos7 nginx 1.10.0
org.springframework.boot
spring-boot-starter-parent
2.0.2.RELEASE
如图:{
使用本地访问cookie浏览器是可以收到cookie的
而我在www.xxx.com下用api.xxx.com是接收不到这个cookie的,
后来我查阅资料发现要设置domain属性
domain 可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”。
}
例如:
document.cookie = “username=Darren;path=/;domain=.csdn.net”
我在 设置domain为.csdn.net,那么我在blog.csdn.net 他的二级域名下就能拿到cookie,
总结:domain表示的是cookie所在的域,默认为请求的地址,如网址为www.study.com/study,那么domain默认为www.study.com。而跨域访问,如域A为t1.study.com,域B为t2.study.com,那么在域A生产一个令域A和域B都能访问的cookie就要将该cookie的domain设置为.study.com;如果要在域A生产一个令域A不能访问而域B能访问的cookie就要将该cookie的domain设置为t2.study.com。注意:一般在域名前是需要加一个".“的,如"domain=.study.com”。
作者:longgege001
来源:CSDN
原文:https://blog.csdn.net/longgege001/article/details/81274088
版权声明:本文为博主原创文章,转载请附上博文链接!
OK,那么原因就找到了,我需要设置domain属性,我们可以看我开头发的图片。但我用localhost访问的时候我的domain是localhost
package com.leyou.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
-
Cookie 工具类
*/
@Slf4j
public final class CookieUtils {/**
- 得到Cookie的值, 不编码
- @param request
- @param cookieName
- @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, null);
}
/**
- 得到Cookie的值,
- @param request
- @param cookieName
- @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String charset) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (charset != null && charset.length() > 0) {
retValue = URLDecoder.decode(cookieList[i].getValue(), charset);
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
log.error(“Cookie Decode Error.”, e);
}
return retValue;
}
public static CookieBuilder newBuilder(HttpServletResponse response) {
return new CookieBuilder(response);
}public static class CookieBuilder {
private HttpServletRequest request;
private HttpServletResponse response;
private Integer maxAge;
private String charset;
private boolean httpOnly = false;public CookieBuilder(HttpServletResponse response) { this.response = response; } public CookieBuilder request(HttpServletRequest request) { this.request = request; return this; } public CookieBuilder maxAge(int maxAge) { this.maxAge = maxAge; return this; } public CookieBuilder charset(String charset) { this.charset = charset; return this; } public CookieBuilder httpOnly() { this.httpOnly = true; return this; } public void build(String cookieName, String cookieValue) { try { if (StringUtils.isBlank(charset)) { charset = "utf-8"; } if (cookieValue == null) { cookieValue = ""; } else if (StringUtils.isNotBlank(charset)) { cookieValue = URLEncoder.encode(cookieValue, charset); } Cookie cookie = new Cookie(cookieName, cookieValue); if (maxAge != null && maxAge > 0) cookie.setMaxAge(maxAge); if (null != request)// 设置域名的cookie //todo cookie.setDomain(getDomainName(request)); cookie.setPath("/"); cookie.setHttpOnly(httpOnly); response.addCookie(cookie); } catch (Exception e) { log.error("Cookie Encode Error.", e); } } /** * 得到cookie的域名 */ private String getDomainName(HttpServletRequest request) { String domainName = null; String serverName = request.getRequestURL().toString(); if (serverName == null || serverName.equals("")) { domainName = ""; } else { serverName = serverName.toLowerCase(); serverName = serverName.substring(7); final int end = serverName.indexOf("/"); serverName = serverName.substring(0, end); final String[] domains = serverName.split("\\."); int len = domains.length; if (len > 3) { // www.xxx.com.cn domainName = domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1]; } else if (len <= 3 && len > 1) { // xxx.com or xxx.cn domainName = domains[len - 2] + "." + domains[len - 1]; } else { domainName = serverName; } } if (domainName != null && domainName.indexOf(":") > 0) { String[] ary = domainName.split("\\:"); domainName = ary[0]; } return domainName; }
}
}
这是我用localhost访问时候的domain=localhost,
然后我换成域名访问
String serverName = request.getRequestURL().toString();
我这个值怎么变成127.0.0.1.8087了???? 讲道理应该是http://api.leyou.com 这样的
原因是我用了nginx反向代理的原因,它把我的url代理成了我win10下面的
加了个
proxy_set_header Host $host
这里先埋个伏笔,因为api网关也有问题
我们还是先把nginx问题解决吧
这样转发的时候就会带上本身的host=api.leyou.com
结果还是不对
这是啥玩意儿呢??????黑人问号????
原因是我的小学zuul 做了代理
我们debug 我们的网关源码查看一下正确性
zuul有很多过滤器,都继承自ZuulFilter我们来看看PreDecorationFilter 前置过滤器
在此处打上断点
zuul网关在此处居然是false,那么我的微服务肯定收不到正确的host了。
OK,问题找到了
这是zuul的默认配置我们改一下就ojbk了
我加了个*
add-host-header: true
好的我们再次debug
进去了,哈哈哈哈, 卧槽?????
还是不对,你mmb是睿智吧直接开喷不解释好吧,因为这是zuul的bug,
RibbonRoutingFilter在这个类下有如下代码
我们跟踪到 isIncludedHeader下
它应该是根据header的hashcode值来判断是不是包含了这些头如果包含了一个就return false
ok我们看buildZuulRequestHeaders这个方法的isIncludedHeader
这不是完蛋了吗,??我要用的host被包含进去了而且spring把代码写死了。这不是扯淡吗,吓得我赶紧换个版本,吃把鸡压压惊
public boolean isIncludedHeader(String headerName) {
String name = headerName.toLowerCase();
RequestContext ctx = RequestContext.getCurrentContext();
if (ctx.containsKey(“ignoredHeaders”)) {
Object object = ctx.get(“ignoredHeaders”);
if (object instanceof Collection && ((Collection)object).contains(name)) {
return false;
}
}
byte var5 = -1;
switch(name.hashCode()) {
case -1132779846:
if (name.equals("content-length")) {
var5 = 2;
}
break;
case -905826493:
if (name.equals("server")) {
var5 = 3;
}
break;
case -775651618:
if (name.equals("connection")) {
var5 = 1;
}
break;
case 3208616:
if (name.equals("host")) {
var5 = 0;
}
break;
case 1050906973:
if (name.equals("x-application-context")) {
var5 = 5;
}
break;
case 1274458357:
if (name.equals("transfer-encoding")) {
var5 = 4;
}
}
switch(var5) {
case 0:
if (this.addHostHeader) {
return true;
}
case 1:
case 2:
case 3:
case 4:
case 5:
return false;
default:
return true;
}
}
这是最新版的isIncludedHeader方法,这回应该没问题了
还是有问题
这是zuul的默认配置
private Set sensitiveHeaders = new LinkedHashSet(Arrays.asList(“Cookie”, “Set-Cookie”, “Authorization”));
原来它把写cookie给禁用了,我们把它设为空就完事了熬
我哭了,你们呢