我正在使用基于会话的授权在不同的域上使用前端和后端应用程序.我已经设置了一个有效的CORS配置,它可以按预期工作localhost(例如从端口:9000到端口:8080).一旦我在安全域上部署应用程序(两个域都只允许HTTPS),在JavaScript中就不再可以访问CSRF cookie,从而导致前端的错误后续请求(缺少CSRF头).
cookie由Set-Cookie标题中的后端设置,不使用HttpOnly标志.它实际上设置在浏览器的某个位置,因为后续请求包含会话cookie和CSRF cookie.尝试通过JavaScript访问它(使用例如document.cookie在控制台中)返回一个空字符串.DevTools of Chrome不会在前端域上显示任何 cookie(后端域甚至没有列出).
我期待cookie被设置并在当前域(前端域)上可见.我正在使用axios库的withCredentials标志.
你有什么想法,为什么不能从JavaScript或Chrome中的DevTools访问cookie?这与Strict-Transport-Security标题有什么关系吗?
1.初始GET响应标头
HTTP/1.1 401 Unauthorized
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://[my-frontend-domain]
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Wed, 20 Sep 2017 11:57:07 GMT
Expires: 0
Pragma: no-cache
Server: Apache-Coyote/1.1
Set-Cookie: CSRF-TOKEN=[some-token]; Path=/
Vary: Origin,Accept-Encoding
X-Content-Type-Options: nosniff
X-Vcap-Request-Id: [some-token]
X-Xss-Protection: 1; mode=block
Content-Length: [some-length]
Strict-Transport-Security: max-age=15768000; includeSubDomainsRun Code Online (Sandbox Code Playgroud)
2.后续POST请求标头
我有一个 PHP 脚本,如果直接在浏览器中(或由邮递员)调用,它会成功返回一些简单的标头以及 set-cookie 标头。我可以从 chrome devTools 读取这样的响应头。但是一旦我通过 Axios 调用它,set-cookie 标头就不会显示,并且浏览器中也没有保存 cookie。
我尝试了不同的事情,比如更改响应头服务器端和使用 "withCredentials: true" 和 axios,但没有任何效果。我什至没有收到错误或任何与 cors 相关的问题。
PHP:
header("Access-Control-Allow-Origin: http://localhost:8080");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST, GET");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
header("Access-Control-Max-Age: 99999999");
setcookie("TestCookie", "Testing", time() + 3600, "/", "localhost", 0);
die();
Run Code Online (Sandbox Code Playgroud)
JS:
Vue.prototype.$http = axios.create({
baseURL: XYZ,
withCredentials: true
})
Run Code Online (Sandbox Code Playgroud)
所以我的第一个问题是为什么直接调用php脚本时会出现header?以及如何存档以通过 axios 获取标题?
我有以下子域:
stream.example.comsub.example.com这两个域都有 SSL 证书并且有效。我正在使用videoJS 7.6.6它具有http_streaming库。
上sub.example.com,有一个视频标签将破折号清单设置为包含指向stream.example.com.VideoJS 的链接的源,sub.example.com在向stream.example.com链接发出请求时需要包含 Laravel cookie,但这并没有发生,当我HAR result从开发人员控制台下载时,我在要求。
我的 VideoJS HTML
<video-js id="player" class="video-js vjs-big-play-centered">
<source src="data:application/dash+xml;charset=utf-8;base64,......." type="application/dash+xml" crossorigin="use-credentials">
</video-js>
Run Code Online (Sandbox Code Playgroud)
mainifest 是有效的,它包含stream.example.com网址
VideoJS
player = window.player = videojs('player', {
html5: {
hls: {
withCredentials: true
}
},
controls : true,
fluid: true,
controlBar: {
children: ['playToggle', 'volumePanel', 'currentTimeDisplay', 'timeDivider', 'durationDisplay', 'progressControl', 'liveDisplay', 'seekToLive', 'remainingTimeDisplay', 'customControlSpacer', 'playbackRateMenuButton', 'chaptersButton', 'descriptionsButton', 'subsCapsButton', 'audioTrackButton', …Run Code Online (Sandbox Code Playgroud) 我有一个 Nuxt 3 (^3.0.0-rc.11) 前端和一个 Golang Echo v4 后端 API。
该属性在 nuxt.config.ts 文件中ssr设置,因此当我运行时,我可以从 echo API 提供静态生成的文件,并且我从后端发送的会话 cookie 按预期在浏览器中设置。falsenpm run generate
但是,当我npm run dev从 nuxt 运行时,浏览器中没有设置 cookie,即使我可以在响应标头中看到它(在 Firefox 的网络选项卡下)。
我可能认为它不适用于开发服务器,因为 nuxt 正在端口上运行:3000并且 echo on :1323,并且可能存在 CORS 问题?
我尝试按照“为跨源请求设置 cookie”中的提示进行操作,但无济于事。我不确定这是否是我的情况的问题。
我什至尝试从v3.nuxtjs.org创建 nuxt 可组合项,但同样,我不确定这是否是问题所在。
服务器.go
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"http://localhost:3000"},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
AllowCredentials: true,
}))
Run Code Online (Sandbox Code Playgroud)
会话.go
session, _ := store.Get(c.Request(), "session")
session.Options = &sessions.Options{
Path: "/",
MaxAge: 86400 * 7, …Run Code Online (Sandbox Code Playgroud) 我在一个网站上https://aaa.shared.com。该网站(称之为)向 url (网站)A发送请求并接收具有以下标头的响应:xhrhttps://zzz.shared.com/some/pathZ
access-control-allow-credentials: true
access-control-allow-origin: aaa.shared.com
set-cookie: foo=bar; expires=Fri, 01 Jan 2100 00:00:00 GMT; path=/; secure; samesite=none; httponly
Run Code Online (Sandbox Code Playgroud)
(我按照这个问题的答案添加access-control标题)
现在,我期望的是,每当我同时在 A 或 Z 上时,每当请求发送到Z(跨源或同源,重要的是请求的 URL)时,浏览器都会添加 cookie,但事实并非如此。 t!此外,我看不到它在浏览器开发人员工具(F12 -> 应用程序 -> Cookies)中设置。我正在使用 Chrome,但目标是跨浏览器解决方案。
我缺少什么?我发现很难找到一些关于Set-Cookie请求不同来源时标头如何工作的详细信息。
编辑:rowan_z最初建议替换samesite=lax为samesite=none,因为这个问题的第一个版本中的 A 和 Z 是完全独立的域(仅共享.com部分)。我尝试了一下,但没有帮助。但现在我意识到它们实际上被视为SameSite,因为它们位于shared.com域的不同子域上。所以现在我相信这samesite=lax在这里也应该起作用。
更新:最后,我只是将应用程序移动aaa.shared.com到具有某个路径的同一子域下zzz.shared.com/aaa/path,因为处理 cookie 和 CORS 确实很困难。此外,将其配置为使用localhost会增加额外的复杂性。
我正在使用 Express-Session 来设置带有 Redis 会话存储的会话 Cookie。当用户登录时,我可以成功设置一个 cookie,通过单击 chrome 中页面 URL 旁边的“锁定”图标并查看 cookie,将其登录,如图所示。然而,当页面刷新时,我的用户会因为 cookie 消失而注销。
如何防止页面刷新时丢失 cookie?
我的会话选项减去我的路线如下所示,我在 https 上运行我的客户端。
let sessionOptions = {
secret: "REDACTED_FROM_STACKOVERFLOW",
resave: true,
name: "redisSession",
expires: new Date(Date.now() + (60 * 1000 * 60 * 100000)),
store: new RedisStore({client: redisClient}),
cookie: {
sameSite: 'none',
secure: true,
httpOnly: true,
maxAge: 1000 * 60 * 1000
},
rolling: true,
saveUninitialized: true
};
app.use(cors({credentials: true, origin: 'https://localhost:8080'}));
const httpsOptions = {
key: fs.readFileSync(process.env.localHostCertKeyPath),
cert: fs.readFileSync(process.env.localHostPemPath)
}
app.use(cookieParser("REDACTED_FROM_STACKOVERFLOW"));
const httpsOptions …Run Code Online (Sandbox Code Playgroud) 前端运行于localhost:3000
服务器运行于localhost:9000
我可以在不访问 cookie 的情况下发出 CORS 请求。
示例 Axios 请求
axios.post(SERVER+'/createUser', params)
.then( resp=>{
//not important
});
Run Code Online (Sandbox Code Playgroud)
(工作:能够从其他服务器访问资源)
我无法保存/发送服务器localhost:9000设置的 HttpOnly cookie [会话实现]
预期流程
拨电至 localhost:9000/authenticate
localhost:9000/authenticate 返回带有 HttpOnly cookie 的响应
localhost:9000携带此 cookie 的后续请求
为了尝试使用 axios 访问此 cookie,我添加了axios 文档withCredentials:true
引用的标头。为清楚起见:
let headers = {
withCredentials:true
}
export function authenticate(creds){
return dispatch => {
axios.post(SERVER+'/authenticate', creds, headers)
.then( resp => {
//not important
});
};
}
Run Code Online (Sandbox Code Playgroud)
之后我收到以下错误:
加载http://localhost:9000/authenticate失败:对预检请求的响应未通过访问控制检查:响应中“Access-Control-Allow-Origin”标头的值不能是通配符“*”当请求的凭据模式为“包含”时。因此,不允许访问Origin ' http://localhost:3000 '。XMLHttpRequest 发起的请求的凭证模式由 withCredentials …
我有以下设置:
现在我有一个应用程序loc可以为子域设置一些cookie loc3。我看到 cookie 在 chrome 网络响应中设置(或假设设置)。
Set-Cookie: MY_COOKIE=YUMM; domain=loc3.localdomain;
expires=Fri, 21-Jun-2019 10:48:58 GMT; path=/coolApp/bro
Run Code Online (Sandbox Code Playgroud)
然后在应用程序 atloc我有一个按钮,可以将用户发送到另一个应用程序 at loc2,将用户重定向到loc3at loc3.localdomain:8092/coolApp/bro/something/more。因此,此时我应该在 的应用程序请求中看到 cookie loc3,但我没有。
Cookie 设置:
FacesContext facesContext = FacesContext.getCurrentInstance();
//facesContext.getExternalContext().addResponseCookie("TEST", "TEST", properties); tried this too
//then in properties will be the maxAge, path and domain set
Cookie cookie = (Cookie) facesContext.getExternalContext().getRequestCookieMap().get("MY_COOKIE");
if(cookie == null){
cookie = new …Run Code Online (Sandbox Code Playgroud) 我正在创建一个小型 MERN 应用程序用于注册、登录,成功登录后,它会显示他们的个人资料。
1.我希望用户登录,如果成功,我会将 user._id 发送到 React 应用程序并将其重定向到 profile/user._id
2.在 ComponentDidMount 方法的配置文件页面,我将执行一个 get-request,使用 user._id 从我的服务器获取用户数据。
3.在此获取请求中,我想检查该用户是否有活动会话,这样即使有人使用 URL:profile/some_user_id,它也始终会检查活动会话。
我的问题是:
1.我是否需要显式地将 cookie 发送给客户端(如果是),那么express-session 将如何为我做到这一点。
2.解决方案1后,当我执行 /profile/id get-request 时,如何在会话中访问此保存的数据。
我的应用程序.js
require('./passport')(passport);
app.use(cookieParser());
//Express session
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: false,
cookie: { maxAge: 60*60*1000 },
})
);
app.use(passport.initialize());
app.use(passport.session());
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if(err) {
res.status(203).send(err);
} else {
if(user) {
req.login(user, err => {
req.session.user …Run Code Online (Sandbox Code Playgroud)