背景
最近在做sso单点登录,sso登录成功后后端需要把token和用户信息以cookie的方式传送给前端,由于项目是前后端分离的,这就涉及到了前后端跨域共享cookie的问题,下面就说说我在项目中的解决思路。
解决思路一 —— 通过二级域名共享cookie
一开始在网上看了很多的跨域共享cookie的方法,使用最多的是jsonp和cors这两种,今天我介绍的是另外一种---基于二级域名共享cookie,原因是简单...(注意:使用二级域名共享cookie有一个限制条件,就是两个域名的二级域名必须相同)
二级域名
先来介绍一下什么是二级域名,拿www.baidu.com做例子,com是这个域名的一级域名,baidu.com是这个域名的二级域名,www.baidu.com是这个域名的三级域名,以此类推...
二级域名共享就是两个域名的的二级域名必须相同,只有符合这个条件它们之间的cookie才能共享。(例如:a.XXX.test.io和b.test.io,这两个域名的二级域名就是相同的)
代码实现(基于JDK1.8)
//添加cookie cookieName
Cookie cookieName = new Cookie("user_name", userName);
cookieName.setDomain("test.io"); //通过二级域名共享cookie
cookieName.setPath("/");
cookieName.setMaxAge(Integer.MAX_VALUE);
cookieName.setSecure(false);
response.addCookie(cookieName);
//添加cookie token
Cookie token = new Cookie("token", token);
token.setDomain("test.io"); //通过二级域名共享cookie
token.setPath("/");
token.setMaxAge(Integer.MAX_VALUE);
token.setSecure(false);
response.addCookie(token);
//关闭浏览器时删除cookie
Cookie token = new Cookie("token", null);
token.setDomain("test.io");
token.setPath("/");
token.setSecure(false);
token.setMaxAge(0); //0代表关闭浏览器删除cookie,负数则关闭浏览器cookie失效(没有删除)
response.addCookie(token);
参数介绍
domain:需要设置的二级域名(至少是二级域名,可以是三级域名、四级域名...)
path:设置可以访问cookie的路径。假如cookie1的path为/test/,cookie2的path为/test/t/,那么test路径下的所有页面都可以访问到cookie1,而cookie2只有/test/t/下的页面才能访问。
maxAge:过期时间(时间单位为秒),设置为负数关闭浏览器该cookie失效,设置为0表示删除该cookie,整数则设置时间过后cookie失效
secure:是否加密方式传输,默认false,为true的话只能使用https协议(因为https协议是加密协议,而HTTP不是)。
解决思路二 —— 通过设置response的header
直接上代码
@RequestMapping(value = "/test.do")
public void testHandler(HttpServletRequest request, HttpServletResponse response){
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, accept, content-type, xxxx");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "http://localhost:8080");
Cookie cookieName = new Cookie("user_name", "test");
cookieName.setPath("/");
cookieName.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookieName);
}
解释:
"Access-Control-Allow-Headers":可选字段,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
"Access-Control-Allow-Methods":可选字段,允许请求该接口的方法类型。
"Access-Control-Allow-Credentials":可选字段。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。
"Access-Control-Allow-Origin":必填字段。它的值要么是请求时Origin字段的值(如示例中http://localhost:8080),要么是一个*,表示接受任意域名的请求。
解决思路三 —— 设置@CrossOrigin
先看代码实现
@CrossOrigin(origins = "http://localhost:8080", maxAge = 3600, methods = {RequestMethod.OPTIONS, RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE})
@RequestMapping(value = "/test.do")
public void testHandler(HttpServletRequest request, HttpServletResponse response){
Cookie cookieName = new Cookie("user_name", "test");
cookieName.setPath("/");
cookieName.setMaxAge(Integer.MAX_VALUE);
response.addCookie(cookieName);
}
@CrossOrigin注解是被注解的方法具备接受跨域请求的功能。默认情况下,它使方法具备接受所有域,所有请求消息头的请求。。。。这个例子中,我们仅接受
http://localhost:8080发送来的跨域请求。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。