首页 > 解决方案 > NGINX 在我的 Web API 中没有正确运行请求

问题描述

我是开发 Web API 的新手,我正试图将我的小型 Web API 发布到我的 VPS 中。问题是我已经设置好了。在这篇文章的后面,我将向您展示 Nginx 配置和所有必要的信息。我遇到的主要问题是,例如,当我调用我的获取 OAuth 令牌请求时,它返回 200 OK 但是当我将承载令牌放入每个请求中时,我将执行 API 总是返回 500 状态代码。我已按照 Microsoft 指南设置 .NET Web API,但我仍然遇到这些问题。我该如何解决这个问题?提前致谢。

获取 OAuth 令牌 获取 OAuth 令牌

使用该令牌获取所有用户请求 获取所有用户请求

API 的 Startup.cs(您可以找到我添加了来自官方 Microsoft Docs 的行)

namespace IncidentManagerAPI
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.KnownProxies.Add(IPAddress.Parse("141.94.23.122"));
            });
            services.AddMvc();
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
            });
            services.AddScoped<IUserInterface, UserService>();
            services.AddScoped<ICompanyInterface, CompanyService>();
            //services.AddControllers();
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "Incident Manager API", Version = "v1", Description = "Welcome to the Incident Manager API, here you will be able to test all API requests for debugging." });
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "bearer",
                    BearerFormat = "JWT"
                });
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                            },
                            new List<string>()
                        }
                });
            });
            services.AddEntityFrameworkNpgsql().AddDbContext<PostgreSQLContext>(opt =>
            opt.UseNpgsql(Configuration.GetConnectionString("PostgreSQLConnection")));
            services
                .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", options => { })
                .AddJwtBearer(options =>
                {
                    options.SaveToken = true;
                    options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
                    {
                        ValidIssuer = "incidentmanagerapi",
                        ValidAudience = "testuser",
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("testpassword")),
                        ClockSkew = TimeSpan.Zero
                    };
                });
            services.AddAuthorization(options =>
            {
                options.DefaultPolicy = new AuthorizationPolicyBuilder(JwtBearerDefaults.AuthenticationScheme).RequireAuthenticatedUser().Build();
                options.AddPolicy("BasicAuthentication", new AuthorizationPolicyBuilder("BasicAuthentication").RequireAuthenticatedUser().Build());
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });

            app.UseAuthentication();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "MyAPI");
                c.RoutePrefix = string.Empty;
            });

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}

Nginx 配置:

    server {

    # SSL configuration
    #
    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;
    #
    # Note: You should disable gzip for SSL traffic.
    # See: https://bugs.debian.org/773332
    #
    # Read up on ssl_ciphers to ensure a secure configuration.
    # See: https://bugs.debian.org/765782
    #
    # Self-signed certs generated by the SSL-cert package
    # Don't use them in a production server!
    #
    # include snippets/snakeoil.conf;

    root /var/www/html/incidentmanagerapi;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name api.incidentmanagerapp.com;

    location / {
        proxy_pass         http://127.0.0.1:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

    # pass PHP scripts to FastCGI server
    #
    #location ~ \.php$ {
    #   include snippets/fastcgi-php.conf;
    #
    #   # With php-fpm (or other unix sockets):
    #   fastcgi_pass unix:/run/php/php7.4-fpm.sock;
    #   # With php-cgi (or other tcp sockets):
    #   fastcgi_pass 127.0.0.1:9000;
    #}

    # deny access to .htaccess files if Apache's document root
    # concurs with Nginx's one
    #
    #location ~ /\.ht {
    #   deny all;
    #}

    listen [::]:443 ssl; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.incidentmanagerapp.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.incidentmanagerapp.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#   listen 80;
#   listen [::]:80;
#
#   server_name example.com;
#
#   root /var/www/example.com;
#   index index.html;
#
#   location / {
#       try_files $uri $uri/ =404;
#   }
#}

server {
    if ($host = api.incidentmanagerapp.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;

    server_name api.incidentmanagerapp.com;
    return 404; # managed by Certbot
}

编辑:

我在 C# 中启用了日志,但仍然不知道如何解决问题:

    System.NullReferenceException: Object reference not set to an instance of an object.
   at IncidentManagerAPI.Controllers.UserService.GetUsers() in C:\Users\alexm\Documents\Projects\.NET\incident-manager-api\IncidentManagerAPI\Services\UserService.cs:line 33
   at IncidentManagerAPI.Controllers.UserController.GetUsers() in C:\Users\alexm\Documents\Projects\.NET\incident-manager-api\IncidentManagerAPI\Controllers\UserController.cs:line 26
   at lambda_method9(Closure , Object )
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImluY2lkZW50bWFuYWdlcmFwcCIsIm5iZiI6MTYyMDIwMjczMCwiZXhwIjoxNjIwMjg5MTMwLCJpYXQiOjE2MjAyMDI3MzAsImlzcyI6ImluY2lkZW50bWFuYWdlcmFwaSIsImF1ZCI6ImluY2lkZW50bWFuYWdlcmFwcCJ9.8-bOVZwpL65sfjSgiebhTipqXZ0Hsy3KIT0cdC22rEs
Cookie: __cfduid=d84134facb9aef7a8993712bbf57b8a5c1617971031
Host: api.incidentmanagerapp.com
User-Agent: PostmanRuntime/7.28.0
X-Forwarded-For: 81.184.7.139
CF-IPCountry: ES
CF-RAY: 64a89a9f2e08b7c9-CDG
CF-Visitor: {"scheme":"https"}
Postman-Token: 06151a4e-e608-43d5-ba42-999f1bfd37b4
CF-Connecting-IP: 81.184.7.139
CDN-Loop: cloudflare
cf-request-id: 09dd3ef77a0000b7c926288000000001
X-Original-For: 127.0.0.1:44558
X-Original-Proto: http

更新:

问题是我在数据库模式中没有权限。

标签: c#nginxwebpostmanwebapi

解决方案


NGINX 配置似乎没问题,我不是 C# 人,所以不确定那部分。

如果您在应用程序错误日志中没有看到值得修复的内容,则可能是 NGINX。您可以发布 NGINX 错误日志中的最后几行吗?


推荐阅读