服务端
跨最高二级域名
有三个域名A .top,,
也就是在产生的cookie,可以与,和共享
要想cookie在跨域在相同父级域名下共享,那么domian属性就应该为:“.
”
跨域设置
// 处理跨域请求,支持options访问
func Cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin")
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Access-Control-Allow-Headers", "Content-Type")
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Content-Type")
//想要cookie正常使用,就要加上这个头部,设置为true
c.Header("Access-Control-Allow-Credentials", "true")
// 放行所有OPTIONS方法
if method == "OPTIONS" {
c.AbortWithStatus(http.StatusNoContent)
}
// 处理请求
c.Next()
}
}
设置cookie
import (
"net/http"
"net/url"
)
var c *gin.centext
userCookie := &http.Cookie{Name: 'user', Value: url.QueryEscape(token), Path: "/", Secure: false, Domain: '.域名', HttpOnly: true, MaxAge: 30 * 24 * 3600}
http.SetCookie(c.Writer, userCookie)
前端
使用的axios,其实也是对Ajax的封装
首先当Ajax请求发生跨域时默认是不会携带cookie的,如果想要携带cookie需要手动为Ajax指定withCredentials属性。
axios
const service = axios.create({
//想要cookie正常使用,就要加上这个头部,设置为true
withCredentials: true,
//这样可以根据页面访问地址,去调后端,便于本地开发测试和线上使用
baseURL: window.location.href.indexOf("localhost") > -1 ? "本地服务端地址" : "域名",
timeout: 30000
})
原生Ajax
var xmlHttpRequest = new XMLHttpRequest()
xmlHttpRequest.withCredentials = true //重点是这一行
xmlHttpRequest.open('get','http://127.0.0.1:53000/getPit')
xmlHttpRequest.onreadystatechange=function(){
if(xmlHttpRequest.readyState==4){
if(xmlHttpRequest.status==200||xmlHttpRequest.status==304){
window.console.log(JSON.parse(xmlHttpRequest.response))
}
}
}
xmlHttpRequest.send()
Jquery
$.get({
type:'get',
url:'http://127.0.0.1:53000/detect',
dataType: "json",
crossDomain:true,//指明需要跨域
//xhrFiled告诉Jquery跨域时携带cookie
xhrFields:{
withCredentials:true
},
success:function(res){
window.console.log(res)
}
})
参考资料
写入第三方的cookie(A域名往B域名下写入的Cookie,对于B域名就是第三方Cookie)
使用场景:
- 精准推送广告
- 无感登录
常用于主系统和多子系统的场景,就是登录主系统后就无需再去登录一次访问子系统了,并且主系统和子系统不在一个主域名下。
一点前提条件:
- 从服务器返回给浏览器的响应如果携带Set-Cookie响应头,可以给当前所在域名写入Cookie
代码实现
思路:
A域名要给B域名共享自己的cookie,就要去调用B域名的一个服务的接口,参数要携带cookie的名称和值等数据,然后接口的实现中要给响应头加上cookie,这样B域名就可以有A域名发过来的cookie了。
B域名的要被调用的接口必须是https的。本地想要测试,可以使用ssl自签名,然后修改hosts文件映射
一、 golang + vue实现
A方:
- 设置A方()自己的cookie(在A方的后端服务中)
这部分根据需求,写在需要的地方,一般就在登录后获取jwt的方法中
function(c *gin.context){
.....省略
userCookie := &http.Cookie{Name:"a_cookie", Value: url.QueryEscape(token), Path: "/", Secure: false, Domain: ""
, HttpOnly: false, MaxAge: 30 * 24 * 3600}
fmt.Println("userCookie:", userCookie)
http.SetCookie(c.Writer, userCookie)
}
.....省略
- 将A方cookie设置进B方的接口方法
func (j *JwtApi) SetCookie(c *gin.Context) {
value := c.Query("cookie")
//这里是想通过jsonp的请求中获取host,也就是B方的域名来作为cookie的domain,
//但是我在线上部署时请求头里面没有Host,这里先埋个坑,这里的domain我就写死
//addr := ("Host")
http.SetCookie(c.Writer, &http.Cookie{
Name: "thirdparty_cookie",
Value: value,
MaxAge: 36000,
Domain: ".",
Path: "/",
Secure: true,
HttpOnly: true,
SameSite: http.SameSiteNoneMode,
})
c.JSONP(200, gin.H{
"message": "success" + "----" + value + "-----" ,
})
}
- 清除B方中的第三方cookie的接口方法
func (j *JwtApi) ClearCookie(c *gin.Context) {
http.SetCookie(c.Writer, &http.Cookie{
Name: "thirdparty_cookie",
Value: "",
MaxAge: -1,
Domain: ".",
Path: "/",
Secure: true,
HttpOnly: true,
SameSite: http.SameSiteNoneMode,
})
c.JSONP(200, gin.H{
"message": "success",
})
}
这样设置下,也会有这个cookie,相同根域名就这样共享了cookie
A方的前端服务:
使用js-cookie获取cookie的名称。这一部分就根据业务需求写在需要的地方
import Cookies from 'js-cookie'
Cookies.get("ds-jwt")
安装jsonp
npm install --save vue-jsonp
import { jsonp } from 'vue-jsonp' //这里就按需引入了,没有全局引入
export const setCookieForSubSystem = (url, value) => {
jsonp(item, {cookie: value}).then(data=>{
console.log("jsonp return =>",data)
})
}
jsonp这里请求会在控制台看见报错,但是呢可以达到想要的效果,怎么处理先埋个坑