Java解决cookie写入问题

当我们使用

 CookieUtils.setCookie(request, response, this.prop.getCookieName(), token, this.prop.getExpire() * 60);
           

将token设置进入cookie时,页面刷新并不能获取到cookie值,这是为什么呢?

问题分析

我们在之前测试时,清晰的看到了响应头中,有Set-Cookie属性,为什么在这里却什么都没有?

我们之前在讲cors跨域时,讲到过跨域请求cookie生效的条件:

  • 服务的响应头中需要携带Access-Control-Allow-Credentials并且为true。

  • 响应头中的Access-Control-Allow-Origin一定不能为*,必须是指定的域名

  • 浏览器发起ajax需要指定withCredentials 为true

看看我们的服务端cors配置:

没有任何问题。

再看客户端浏览器的ajax配置,我们在js/common.js中对axios进行了统一配置:

一切OK。

那说明,问题一定出在响应的set-cookie头中。我们再次仔细看看刚才的响应头:

我们发现cookie的domain属性似乎不太对。

cookie也是有的限制,一个网页,只能操作当前域名下的cookie,但是现在我们看到的地址是0.0.1,而页面是www.xx.com域名不匹配,cookie设置肯定失败了!

跟踪CookieUtils

我们去Debug跟踪CookieUtils,看看到底是怎么回事:

我们发现内部有一个方法,用来获取Domain:

它获取domain是通过服务器的host来计算的,然而我们的地址竟然是:127.0.0.1:8087,因此后续的运算,最终得到的domain就变成了:

问题找到了:我们请求时的serverName明明是:api.xx.com,现在却被变成了:127.0.0.1,因此计算domain是错误的,从而导致cookie设置失败!

解决方法:

1、替换spring的jdk

Finchley.SR1版本会存在获取不到cookie值的bug,所以要spring-cloud-dependencies替换成Finchley.RELEASE版本。

2、解决host地址的变化

这里的server name其实就是请求的时的主机名:Host,之所以改变,有两个原因:

  • 我们使用了nginx反向代理,当监听到api.leyou.com的时候,会自动将请求转发至127.0.0.1:10010,即Zuul。

  • 而后请求到达我们的网关Zuul,Zuul就会根据路径匹配,我们的请求是/api/auth,根据规则被转发到了 127.0.0.1:8087 ,即我们的授权中心。

我们首先去更改nginx配置,让它不要修改我们的host:proxy_set_header  Host  $host;

把nginx进行reload: nginx -s reload

这样就解决了nginx这里的问题。但是Zuul还会有一次转发,所以要去修改网关的配置(xxx-gateway工程):

重启后,我们再次测试。

最后计算得到的domain:

3、Zuul的敏感头过滤

Zuul内部有默认的过滤器,会对请求和响应头信息进行重组,过滤掉敏感的头信息:

会发现,这里会通过一个属性为SensitiveHeaders的属性,来获取敏感头列表,然后添加到IgnoredHeaders中,这些头信息就会被忽略。

而这个SensitiveHeaders的默认值就包含了set-cookie

全局设置:

zuul.sensitive-headers= 

思路都是把敏感头设置为null

最后的测试

 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
JavaCookie是一个Java库,可以用来处理cookie。要实现自动登录,可以使用JavaCookie来保存登录凭证(如用户名和密码)的cookie,然后在每次访问需要登录的页面时,检查是否存在登录凭证的cookie,并根据cookie中的信息进行自动登录。 以下是一个简单的示例代码,演示了如何使用JavaCookie来实现自动登录: ```java import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import com.github.javaxcelstefan.javacookie.Cookies; public class AutoLoginExample { private static final String LOGIN_URL = "https://example.com/login"; private static final String SECRET_PAGE_URL = "https://example.com/secret"; public static void main(String[] args) throws IOException { Cookies cookies = new Cookies(); // 检查是否存在登录凭证的cookie,并根据cookie中的信息进行自动登录 if (cookies.containsKey("username") && cookies.containsKey("password")) { String username = cookies.get("username").getValue(); String password = cookies.get("password").getValue(); if (login(username, password)) { System.out.println("自动登录成功!"); } else { System.out.println("自动登录失败,需要手动登录。"); } } else { System.out.println("没有保存登录凭证的cookie,需要手动登录。"); } // 访问需要登录才能访问的页面 String secretPageContent = getSecretPageContent(cookies); System.out.println(secretPageContent); // 保存登录凭证的cookie,以便下次自动登录 cookies.put("username", "USERNAME"); cookies.put("password", "PASSWORD"); } private static boolean login(String username, String password) throws IOException { // 发送POST请求进行登录 URL url = new URL(LOGIN_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); Map<String, String> parameters = new HashMap<>(); parameters.put("username", username); parameters.put("password", password); String postData = String.join("&", parameters.entrySet().stream() .map(entry -> entry.getKey() + "=" + entry.getValue()) .toArray(String[]::new)); connection.getOutputStream().write(postData.getBytes()); int responseCode = connection.getResponseCode(); connection.disconnect(); return responseCode == 200; // 如果返回码是200,则表示登录成功 } private static String getSecretPageContent(Cookies cookies) throws IOException { // 发送GET请求获取需要登录才能访问的页面的内容 URL url = new URL(SECRET_PAGE_URL); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); cookies.setCookies(connection); // 设置Cookie Scanner scanner = new Scanner(connection.getInputStream()); String content = scanner.useDelimiter("\\A").next(); scanner.close(); connection.disconnect(); return content; } } ``` 在上面的示例中,我们使用了JavaCookie来保存用户名和密码的cookie,并在访问需要登录才能访问的页面时,将cookie设置到HTTP连接中。如果存在保存的登录凭证的cookie,则会尝试自动登录,如果登录成功,则可以直接访问需要登录才能访问的页面。如果登录失败,则需要手动登录。登录成功后,我们将保存登录凭证的cookie写入JavaCookie中,以便下次自动登录。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值