【问题标题】:Cookies are not saved in the browserCookie 不会保存在浏览器中
【发布时间】:2021-03-09 20:59:03
【问题描述】:

首先,我想说我已经阅读了有关此问题的几乎所有内容,但到目前为止还没有解决方案。

简而言之,我有一个在 localhost:3000 上运行的 Node.js API 服务器。我还在 localhost:4200 上运行了一个 Angular 10 应用程序。问题很简单 - 我向 localhost:3000/api/users/login 发出请求并收到以下信息: server-response

但是,您可以在此处看到没有保存 cookie:empty-cookies

因此,每个后续请求(无论是 POST 还是 GET)都没有标头,服务器无法识别用户。 到目前为止,我尝试过:

  • 将 { withCredentials: true } 包含到来自 angular 的 http 请求中
  • 将 cookie 更改为 http: false
  • 将 cookie 中的域设置为“.app.localhost”等各种内容
  • 将 sameSite: 'none' 添加到 cookie 中
  • 在运行 API 的 localhost:3000 上搜索 cookie
  • 将 cors 中的原点更改为“*”或完全删除它
  • 在 Edge 中也尝试了所有这些东西(否则我使用 Chrome)

不幸的是,这些东西都不适合我。否则登录和注册成功,我可以在 mongo 中看到数据。

这里我将添加我使用的代码的sn-ps:

const app = express();
app.use(express.json());
app.use(cookieParser(config.cookieSecret));
app.use(express.static(path.resolve(__basedir, 'static')));
app.use(cors({
  origin: config.origin,
  credentials: true
}));
app.use('/api', apiRouter);
app.use(errorHandler);

这是我设置 cookie 的登录处理程序:

async function login(req, res, next) {
const { email, password } = req.body;
try {
    let user = await User.findOne({ email });
    const match = await user.matchPassword(password);
    if (!match) {
        res.status(401)
            .send({ message: 'Wrong username or password' });
        return
    }
    user = bsonToJson(user);
    const token = utils.jwt.createToken({ id: user._id });
    if (process.env.NODE_ENV === 'production') {
        res.cookie(authCookieName, token, { httpOnly: true, sameSite: 'none', secure: true })
    } else {
        res.cookie(authCookieName, token, { httpOnly: true })
    }
    res.status(200).send(user);
} catch (err) {
    next(err);
}

}

这里是 Angular 部分:

loginMet(data) {
return this.http.post('http://localhost:3000/api/users/login', data, {withCredentials: true});

}

【问题讨论】:

    标签: node.js angular express cookies jwt


    【解决方案1】:

    更新

    经过测试,似乎 chrome (86.0.4240.198) 仍然允许在 localhost 上使用跨站点 cookie,这意味着您的问题不是由新限制引起的,使用 { useCredentials: true } 应该可以正常工作。

    首字母

    要被视为具有相同来源的两个位置,协议、域和端口必须相同。在您的情况下,您有(localhost:3000 和 localhost:4200),并且无法在 Safari、Firefox 和 Chrome 中的 2020 年跨不同来源共享 cookie。

    你可以阅读更多关于主题here的内容。

    在本地,您可以尝试通过创建 proxy.config.json 来解决此问题,以便 webpack 开发服务器充当后端的代理。所以所有对 localhost:3000 的请求都会被发送到 localhost:4200。你可以阅读更多关于它的信息here

    另一种适用于本地和生产环境的解决方案(如果您不会从与 API 相同的服务器为 Angular 应用程序提供服务)是为各个应用程序设置一个域和两个子域。在本地,您可以通过更新 hosts file 来执行此操作,当然这将由 DNS 服务器完成。

    【讨论】:

    • 感谢您的资源,不幸的是在 src/ 文件夹中创建 proxy.config.json 并将其添加到 angular.json -> "architect" -> "serve" -> "options" -> "proxyConfig": "src/proxy.config.json" 在 Angular 网站上写的对我不起作用。我使用了默认配置,只更改了目标,因为在我的情况下,API 在端口 3000 上。我也尝试了他们的,目标是 3000,但仍然没有成功。我的配置文件如下所示: { "/api": { "target": "localhost:4200", "secure": false } }
    • 使用默认配置不会自动为您工作。你必须玩弄配置。尝试将 json 更改为 js 文件,如 here 所示,然后尝试 thisthis
    • 我发现了问题所在。 {withCredentials: true} 由于某种原因不适用于 http.post。当我在服务器和 Angular 中将方法更改为 GET 时,请求标头已发送。
    • 这个。代理帮帮我。我的代理配置文件如下所示: { "/api": { "target": "localhost:3000", "secure": false } } 现在我的请求转到 localhost:4200/api 而不是 localhost:3000/api并且代理重定向到正确的地址。谢谢老兄!
    【解决方案2】:

    user1 的回答部分正确。

    自 2020 年 2 月起,RFC 6265 更改了“HTTP 状态管理机制”。 Cookie 现在以默认值 LAX 存储,这会强制浏览器不向第三方提供 cookie。

    Firefox v69 和 Google Chrome(大约一年后)在 80 版中采用了这一方法。

    为避免这种情况,您必须在创建 cookie 时设置以下内容:

    SameSite=无 安全=真

    注意:这些道具只能在开发模式下使用,因为它们会以某种方式将客户端暴露给漏洞!

    来源:

    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite https://www.rfc-editor.org/rfc/rfc6265#section-4.1

    【讨论】:

    • 当您有安全连接 (HTTPS) 时,通常会使用 Secure 标志。
    • 感谢您的信息。使用 {withCredentials: true} 时问题确实得到了解决。我不知道为什么我第一次尝试它时它不起作用。未对代码进行进一步更改。
    猜你喜欢
    • 1970-01-01
    • 2012-12-29
    • 2018-11-19
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多