c# - NGINX 在我的 Web API 中没有正确运行请求
问题描述
我是开发 Web API 的新手,我正试图将我的小型 Web API 发布到我的 VPS 中。问题是我已经设置好了。在这篇文章的后面,我将向您展示 Nginx 配置和所有必要的信息。我遇到的主要问题是,例如,当我调用我的获取 OAuth 令牌请求时,它返回 200 OK 但是当我将承载令牌放入每个请求中时,我将执行 API 总是返回 500 状态代码。我已按照 Microsoft 指南设置 .NET Web API,但我仍然遇到这些问题。我该如何解决这个问题?提前致谢。
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
更新:
问题是我在数据库模式中没有权限。
解决方案
NGINX 配置似乎没问题,我不是 C# 人,所以不确定那部分。
如果您在应用程序错误日志中没有看到值得修复的内容,则可能是 NGINX。您可以发布 NGINX 错误日志中的最后几行吗?
推荐阅读
- c++ - 用于在二叉树中搜索重复值的布尔检查
- java - Spring Boot 2下activiti后启动liquibase
- javascript - 从 PHP 文件中的脚本调用 PHP 文件
- java - 尝试访问列 Java CSV 时出现问题
- java - 使用 log4j 2.13 时禁用 ORMLite 日志
- node.js - 服务器上的 base64 转换 - NodeJS
- php - 如何在php中对数组值求和?
- c# - 在循环内使用 LINQ 实体框架表达式中的变量获取最后一个值
- go - 使用 CloudSQL 和 Google App Engine 使用 Gorm 部署 Go 后端时出现服务器错误 500
- c# - 为什么我的 WPF 应用程序加载动画钢冻结?