admin管理员组

文章数量:814956

向API发出POST请求时出错:ECONNREFUSED

我有一个由SPA,Express.js服务器和ASP NET Core MVC API组成的系统。

我的服务器使用Passport.js以便与外部提供程序一起使用OAuth,因此,除了登录表单之外,我还可以在SPA中提供SSO选项。它的工作方式是,在从提供程序获取用户信息后,它会通过POST请求将此数据发送到API,以对用户进行身份验证。如果用户选择使用登录表单而不是SSO选项之一,它将使用用户的电子邮件和密码直接向API发送POST请求。

到目前为止,在本地工作我没有任何问题。我被要求对系统进行容器化,因此我为每个组件创建了一个Dockerfile,一个docker-compose.yml来聚合它们,运行docker-compose build和docker-compose都没有问题。

现在,运行容器,如果我通过表单选择登录,则可以毫无问题地使用我的SPA,但是如果我尝试使用SSO,则对API进行POST请求时会收到ECONNREFUSED错误,这是很奇怪,因为我的SPA服务向同一地址发出HTTP请求没有问题。

webportal.client_1      | Error: connect ECONNREFUSED 127.0.0.1:8443
webportal.client_1      |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1142:16) {
webportal.client_1      |   errno: -111,
webportal.client_1      |   code: 'ECONNREFUSED',
webportal.client_1      |   syscall: 'connect',
webportal.client_1      |   address: '127.0.0.1',
webportal.client_1      |   port: 8443,
webportal.client_1      |   response: undefined
webportal.client_1      | }

这是我的Server.ts

import bodyParser from "body-parser";
import express from "express";
import session from "express-session";
import passport from "passport";
import { initialiseAuthentication } from "./auth";
import path from "path";
import http from "http";

require("dotenv").config({
  path: __dirname + `/./../.env.${process.env.NODE_ENV}`,
});

const app = express();
const port = process.env.PORT || 5000;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, "/../build")));

app.use(session({ secret: "The big secret" }));

app.get("/ping", (req, res) => {
  res.send({ express: "Pong" });
});

app.use(passport.initialize());

initialiseAuthentication(app);

app.get("*", (req, res) => {
  res.sendFile(path.join(__dirname + "/../build/index.html"));
});

http.createServer(app).listen(port, '0.0.0.0');
console.log(`Listening on port ${port}`);

服务器向其发出HTTP请求的我的应用程序

import request from "superagent";

async function verifyUser(
  email: string,
  name: string,
  provider: string,
  providerId: string
) {
  return await request
    .post(`${process.env.BACKEND_API_URL}/authentication/externalAuth`)
    .send({
      Email: email,
      Name: name,
      Provider: provider,
      ProviderId: providerId,
    })
    .then((res) => {
      return res;
    })
    .catch((err) => {
      console.error(err);
    });
}

async function getUserById(data) {
  return await request
    .get(`${process.env.BACKEND_API_URL}/user/${data.Id}`)
    .auth(data, { type: "bearer" })
    .then((res) => {
      return res;
    })
    .catch((err) => {
      console.error(err);
    });
}

export { verifyUser, getUserById };

SPA中的我的AuthenticationService.ts

import request from "superagent";
import Cookies from "js-cookie";

export async function SignIn(email: string, password: string) {
  return request
    .post(
      `${process.env.REACT_APP_API_BACKEND_URL}/authentication/internalAuth`
    )
    .send({ username: email, password: password });
}

export async function GetUserInfo(userId: number) {
  const jwt = Cookies.get("jwt");
  return request
    .get(`${process.env.REACT_APP_API_BACKEND_URL}/user`)
    .query({ id: userId })
    .auth(jwt as string, { type: "bearer" })
    .then((res) => {
      return res.body;
    })
    .catch((err) => console.error(err));
}

如果有人能够为我澄清这个问题并可能解决,我将非常感谢。谢谢。

编辑1:请求全部在HTTPS中,是的,我启用了允许所有内容的CORS。

Edit 2:添加了Docker-Compose和Dockerfiles。

Docker-撰写

version: "3"
services:
  db:
    image: "mcr.microsoft/mssql/server"
    ports:
      - "1433:1433"
    environment:
      SA_PASSWORD: "VeryStrongPassword1234"
      ACCEPT_EULA: "Y"

  migrations:
    build:
      context: .
      dockerfile: migrations.Dockerfile
    depends_on:
      - db

  api:
    ports:
      - "8080:80"
      - "8443:443"
    environment: 
      - ASPNETCORE_URLS=https://+:443;http://+80
      - ASPNETCORE_Kestrel__Certificates__Default__Password=VeryStrongPassword123
      - ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
    volumes: 
      - ../certs/:/https/
    build:
      context: .
      dockerfile: api.Dockerfile
    depends_on:
      - migrations

  spa_server:
    ports:
      - "5000:5000"
    build: 
      context: ../client
      dockerfile: client.Dockerfile

迁移Dockerfile

#Get base SDK Image from Microsft
FROM mcr.microsoft/dotnet/core/sdk:3.1 as build-env
WORKDIR /app

#Restore any dependecies
COPY ./Migrations ./Migrations
COPY ./Main/appsettings.json ./.Main/appsettings.json
COPY ./Main/appsettings.Development.json ./Main/appsettings.Development.json
COPY ./Roles.Persistence ./Roles.Persistence
COPY ./Users.Persistence ./Users.Persistence
RUN dotnet restore ./Migrations/Migrations.csproj

#Build our release
RUN dotnet publish ./Migrations/Migrations.csproj -c Release --no-restore

#Generate runtime image
FROM mcr.microsoft/dotnet/core/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/Migrations/bin/Release/netcoreapp3.1/publish/ .
ENTRYPOINT ["dotnet","Migrations.dll"]

API Dockerfile

#Get base SDK Image from Microsft
FROM mcr.microsoft/dotnet/core/sdk:3.1 as build-env
WORKDIR /app

#Restore any dependecies
COPY . ./
RUN dotnet restore ./Main/Main.csproj

#Build our release
RUN dotnet publish ./Main/Main.csproj -c Release --no-restore

#Generate runtime image
FROM mcr.microsoft/dotnet/core/aspnet:3.1
WORKDIR /app
EXPOSE 80 443
COPY --from=build-env /app/Main/bin/Release/netcoreapp3.1/publish/ .
ENTRYPOINT ["dotnet","Main.dll"]

SPA和服务器Dockerfile

# Get base image from Node
FROM node:latest as build-env
WORKDIR /app

# Restore dependencies
COPY . ./
RUN npm i -g env-cmd
RUN npm i -g npm-run-all
RUN yarn

# Build client
RUN yarn build:container

# Generate image
EXPOSE 5000
ENTRYPOINT ["yarn", "start:container"]
回答如下:

我解决了。

我使用的端口出了问题。为了使SPA能够从浏览器发出请求,我需要使用外部端口8443。因此,在容器中运行的服务器需要调用内部端口443,现在它正在以打算的。

谢谢大家。

本文标签: 向API发出POST请求时出错ECONNREFUSED