最近在作sso單點登陸,sso登陸成功後後端須要把token和用戶信息以cookie的方式傳送給前端,因爲項目是先後端分離的,這就涉及到了先後端跨域共享cookie的問題,下面就說說我在項目中的解決思路。前端
一開始在網上看了不少的跨域共享cookie的方法,使用最多的是jsonp和cors這兩種,今天我介紹的是另一種---基於二級域名共享cookie,緣由是簡單...(注意:使用二級域名共享cookie有一個限制條件,就是兩個域名的二級域名必須相同)json
二級域名
先來介紹一下什麼是二級域名,拿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不是)。瀏覽器
直接上代碼服務器
@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),要麼是一個*,表示接受任意域名的請求。cookie
先看代碼實現app
@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註解是被註解的方法具有接受跨域請求的功能。默認狀況下,它使方法具有接受全部域,全部請求消息頭的請求。。。。這個例子中,咱們僅接受cors
http://localhost:8080發送來的跨域請求。前後端分離