Home > Software engineering >  Accessing asp.net core api from react app (both containerized)
Accessing asp.net core api from react app (both containerized)

Time:10-10

So I have a containerized app which consists of react asp.net core keycloak nginx.

I don't want to publish the port of the API to the internet, I only want it to be accessible in the containers' network.

But I can't manage to make my API calls from the React app.

Right now I'm doing them here:

https://localhost:7266

docker-compose of asp.net core container

mediere-api:
    container_name: best-asp.net
    image: ${DOCKER_REGISTRY-}mediere-api
    build:
      context: ..
      dockerfile: Dockerfile
    env_file:
        - .env
    depends_on:
            - db
    expose:
      - "7266"
    volumes:
        - ../certs/certificate.pfx:/etc/https/certs

dockerfile of it

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["mediere-API.csproj", "."]
RUN dotnet restore "mediere-API.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "mediere-API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "mediere-API.csproj" -c Release -o /app/publish 

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "mediere-API.dll"]

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    deleted
  }
}

launchSettings.json

{
  "profiles": {
    "mediere_API": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      },
      "applicationUrl": "https://localhost:7266",
      "dotnetRunMessages": true
    },
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Production"
      }
    },
    "Docker": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
      "publishAllPorts": true,
      "useSSL": true
    }
  }
}

.env

#ASP.Net core
ASPNETCORE_STATICWEBASSETS="/app/bin/Debug/net6.0/mediere-api.staticwebassets.runtime.CT.json"
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=https://localhost:7266

Proogram.cs

using mediere_API.DataLayer;
using mediere_API.DataLayer.Repository.Implementations;
using mediere_API.DataLayer.Repository.Interfaces;
using mediere_API.Extensions;
using mediere_API.Middleware;
using mediere_API.Processors.Implementations;
using mediere_API.Processors.Interfaces;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

//Servicii
builder.Services.AddControllers();
builder.Services.ConfigureSwagger();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddRouting(options => options.LowercaseUrls = true);

builder.Services.AddRepositories();
builder.Services.AddProcessors();

//UnitsOfWork
builder.Services.AddScoped<ISchemaUnitOfWork, SchemaUnitOfWork>();
builder.Services.AddScoped<IMainUnitOfWork, MainUnitOfWork>();

//AutoMapper
builder.Services.AddAutoMapper(typeof(Program));
//Keycloak
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
    {
        o.MetadataAddress = "https://keycloak:8443/auth/realms/best-realm/.well-known/openid-configuration";
        o.Authority = "https://keycloak:8443/auth/realms/best-realm";
        o.Audience = "account";
        o.RequireHttpsMetadata = false;
    });
//CORS
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(
        policy =>
        {
            policy.AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod()
                .WithExposedHeaders("FileName");
        });
});

builder.Services.AddDbContext<EfDbContext>();
builder.Services.AddDbContext<SchemaEfDbContext>();


var app = builder.Build();
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();

app.UseMiddleware<SchemaHandlingMiddleware>();

app.UseCors();

app.UseAuthorization();

app.MapControllers();

app.Run();

With these settings, my API calls don't seem to reach the Docker container. I get:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:7266/api/proiecte. (Reason: CORS request did not succeed). Status code: (null)

status code null means that the container couldn't be reached I think.

So what's wrong with my settings?

How should I do my API calls to the ASP container from docker in order for them to work?

Thanks.

CodePudding user response:

  • Same Origin serving approach using reverse proxy:

    You should reverse proxy your API inside your nginx configuration. Something like this:

    nginx.conf:

    location / proxy_pass: TO_YOUR_REACT_APP or: SERVER_YOUR_REACT_APP_STATIC_FILES

    location /api proxy_pass: TO_YOUR_API

    This approach makes your API and REACT app to be at the same origin. So there will be no CORS error.

  • Enabling CORS for requests that you are sending via browser. Please share a screen shot from your browser console error in order th help you with.

  • Related