NGINX 在我的 Web API 中没有正确运行请求

Posted

技术标签:

【中文标题】NGINX 在我的 Web API 中没有正确运行请求【英文标题】:NGINX not running properly requests in my Web API 【发布时间】:2021-05-04 08:57:28 【问题描述】:

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

获取 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

更新:

问题是我在数据库架构中没有权限。

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

刚刚在nginx的access.log中找到了这个:controlc.com/230c8ab9 /etc/nginx/error.log 文件中有什么内容吗? 没什么奇怪的,但谢谢你告诉我。

以上是关于NGINX 在我的 Web API 中没有正确运行请求的主要内容,如果未能解决你的问题,请参考以下文章

Ngrok 没有正确地隧道 Nginx

自托管 web api 并从单元测试项目中访问它

Java Web Services API,但是我无法在我的服务器上运行 JVM

在我的 UI 中选择图像如何停止我的 Web API?

jQuery Datatables AJAX 请求未正确命中 Web API

Laravel+Homestead+nginx 代理:在我的路线中获取正确的 url