1

背景

最近在做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发送来的跨域请求。


princekin
237 声望23 粉丝