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 中没有正确运行请求的主要内容,如果未能解决你的问题,请参考以下文章