NodeJS Angular 不发送Cookie

qltillow  于 2023-03-08  发布在  Node.js
关注(0)|答案(3)|浏览(128)

我的Angular11(http://localhost:4200)现在正在与我的节点API服务器(http://localhost:3000)通信。API服务器在cookie中发送回会话ID,但随后的浏览器对API的请求不附带cookie。
这是节点API在cookie中发回会话ID的方式

res.cookie('sessionID', 123);

F12确认它位于响应标头中,Set-Cookie: sessionID=123; Path=/
Cookie应该是由浏览器自动发送的每个请求。要在节点中读取它:var mysessionid=req.cookie["sessionID"];
已尝试this postgithub中提到的选项,但在F12的请求标头中仍然看不到sessionID

const httpOptions = 
      {
          headers: new HttpHeaders({'Content-Type': 'application/json', 'Access-Control-Request-Headers': 'content-type'}),
          withCredentials: true,
      };
this.http.post<any[]>('http://localhost:3000/anywhere', httpOptions, myData).subscribe(...);

以及:

const httpOptions = 
      {
          headers: new HttpHeaders({'Content-Type': 'application/json'}),
          withCredentials: true,
          'Access-Control-Allow-Headers': 'content-type'
      };

我有一个拦截器在Angular ,以确认如果拦截器造成这没有cookie发送,上述网址被排除,这意味着头部没有接触。仍然cookie没有发送到API服务器。
既然cookie应该是自动发送的,我做得对吗?

qgelzfjb

qgelzfjb1#

当我们的节点API返回一个有效的令牌,或者返回一个刷新令牌时,我们手动设置cookie,如下所示,并且循环axios http请求定义并更新默认的报头。这强制所有前进的HTTP请求在报头中具有用于前进的HTTP请求的更新令牌
当我们的应用程序加载时,我们从头中提取令牌,并在初始加载时将它们设置为axios

// setHTTPToken.js (UI code)

const cookies = require('../../lib/cookies')
const { AUTHTOKEN, DOMAIN } = require('../../lib/constants')
const { NINETYDAYSASSECONDS } = require('./config')
const http = require('../../lib/http')
const { cloneDeep } = require('lodash')
const log = require('../../lib/log')('containers:App:setHTTPToken')

function setHTTPToken (token) {
  log.debug('iterating over axios http methods and setting Authorization token')
  Object.entries(http).map(name => {
    const KEY = name[0]
    // we skip over any AXIOS interfaces we dont need to update headers on
    const skippers = ['ES']
    if (!skippers.includes(KEY)) {
      const headers = cloneDeep(http[KEY].defaults.headers)
      headers.common.Authorization = token
      http[KEY].defaults.headers = headers
    }
  })
  cookies.set(AUTHTOKEN, token, NINETYDAYSASSECONDS, process.env.NODE_ENV === 'production' ? DOMAIN : null)
}

module.exports = setHTTPToken

包含axios路由定义的http文件示例

// http.js (UI code)
import axios from 'axios'

export const OAUTH = axios.create({
  baseURL: process.env.OAUTH_API,
  headers: {
    'Content-Type': 'application/json'
  }
})

export const RL = axios.create({
  baseURL: process.env.RECEIVING_LOG_API,
  headers: {
    'Content-Type': 'application/json'
  }
})

// ...

忽略es5和es6代码的混合,webpack捆绑它们

vwkv1x7d

vwkv1x7d2#

这可能是因为您在端口4200上运行Angular的开发服务器,而API服务器在另一个端口上运行。

t5zmwmid

t5zmwmid3#

最后我能够解决它,使他们SSL,花了我一个多星期:(
希望会帮助人前进。
环境:

  1. Angular 11前端使用第三方身份验证,例如Google。
  2. API服务器是节点14。
    1.两者都是httpS/SSL。
    解决方案:
    1.按照this article创建受信任的.crt.key文件
    1.我没有将localhost添加到hosts文件。
    1.添加proxy.conf.js(或格式一致的. json文件)并将其包含到angular.json文件中。
    1.不需要为每个单独的http调用指定httpOption
  3. API节点,将这两个文件添加到server.js中。
    • Angular 代理配置js**:
const PROXY_CONFIG = 
[
    {
        context: 
        [
            "/path1",      
            "/path2",
            ...
        ],
        "target" : "https://localhost:3001", // I use 3000 for non-SSL
        "changeOrigin": true,  // helps on CORS Error in F12
        "logLevel": "debug",
        "rejectUnauthorzied": true, // must be false if not specify here
        "secure": false,            // PROD must be "true", but DEV false else "UNABLE_TO_VERIFY_LEAF_SIGNATURE"
        "strictSSL": true,          // must be false if not specify here
        "withCredentials": true     // required for Angular to send in cookie
    }
]
module.exports = PROXY_CONFIG;
    • Angular. json**(仅添加"ssl": true,这足以通过SSL运行Angular 11):
"architect": {
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "myapp:build",
            "ssl": true,
            "proxyConfig": "src/proxy.conf.js"
            ...
    • Angular 启动. json**(端口4201用于调试):
{
    "type": "chrome",
    "request": "launch",
    "name": "F5 against localhost",
    "port": 4201,
    "url": "https://localhost:4200",
    "webRoot": "${workspaceFolder}"
}
    • 节点服务器. js**:
const fs = require("fs");
const HttpSOptions = 
    {
        key: fs.readFileSync('ssl\\server.key'),
        cert: fs.readFileSync('ssl\\server.crt')
    }
const httpSServer = httpS.createServer(HttpSOptions, app);
httpSServer.listen(3001, ()=>{console.log('httpS is on 3001');});

要验证证书是否完全受Chrome信任,请在Chrome中打开一个API URL调用,例如http://localhost:3001/path1/func/xyz,您不会看到此消息

相关问题