我正在将我的 Web api 部署到安装了 Ubuntu 23.04 的 VPS。我已经安装了 .net 7 sdk 和 nginx 等。但是当我尝试从任何 api 应用程序访问 api 来请求一些数据时,我收到此错误:
'连接 ID“0HMT9CF8GN50H”,请求 ID“0HMT9CF8GN50H:00000001”: 应用程序引发了未处理的异常。 SoriooWebApi[365268]:System.ArgumentNullException:值不能为 null。 (参数's')'
实际上是 JWT Bearer 错误,这是 Program.cs:
global using Microsoft.EntityFrameworkCore;
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using Retyoo.Data;
using Retyoo.Data.Auth;
using Retyoo.Models;
using Retyoo.WebApi.Data.Auth;
using Retyoo.WebApi.Mappings;
using Retyoo.WebApi.Helpers;
using Retyoo.WebApi.Services;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
//Add DB
builder.Services.AddControllers();
builder.Services.AddHttpContextAccessor();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// builder.Services.AddDbContext<AppDbContext>(options => {
// options.UseNpgsql(builder.Configuration.GetConnectionString("RetyooDatabase"), assembly => assembly.MigrationsAssembly(typeof(AppDbContext).Assembly.FullName));
// });
builder.Services.AddDbContext<AppDbContext>(options => {
options.UseNpgsql(builder.Configuration.GetConnectionString("SoriooDB"), assembly => assembly.MigrationsAssembly(typeof(AppDbContext).Assembly.FullName));
});
//Email config
builder.Services.Configure<EmailSettings>(builder.Configuration.GetSection("EmailConfiguration"));
//Add Identity
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => {
options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
})
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
//Config Identity
builder.Services.Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 6;
options.Password.RequireDigit = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireLowercase = false;
options.Password.RequireUppercase = false;
options.SignIn.RequireConfirmedEmail = true;
options.User.RequireUniqueEmail = true;
}
);
//Add Authentication and JwtBearer
builder.Services
.AddAuthentication(options => {
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = builder.Configuration["AppSettings:ValidIssuer"],
ValidAudience = builder.Configuration["AppSettings:ValidAudience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["AppSettings:Secret"]!)),
};
})
.AddGoogle(googleOptions => {
googleOptions.ClientId = builder.Configuration["Authentication:GoogleWebClientId"]!;
googleOptions.ClientSecret = builder.Configuration["Authentication:ClientSecret"]!;
});
builder.Services.AddAutoMapper(typeof(AutoMapperProfiles).Assembly);
//Inject app Dependencies (DI)
builder.Services.AddScoped<IAuthRepository, AuthRepository>();
builder.Services.AddScoped<ITokenRepository, TokenRepository>();
builder.Services.AddScoped<ICategoryService, CategoryService>();
builder.Services.AddScoped<IImageService, ImageService>();
builder.Services.AddScoped<ISellerService, SellerService>();
builder.Services.AddScoped<ISellerCompanyService, SellerCompanyService>();
builder.Services.AddTransient<IEmailService, EmailService>();
//pipeline
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
} else {
app.UseHttpsRedirection();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
这是appsettings.json 文件:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"SoriooDB": "Host=localhost;Port=5432;Database=sorioodb;User Id=xxx;Password=xxx;"
},
"AppSettings": {
"ValidIssuer": "http://localhost:5000",
"ValidAudience": "http://localhost:3000",
"Secret": "Asdad9DSADAOSDJADA=D)ASDAJADSALKSAD=ASKASDlkerjelkjadaşkAADKLJLK)=(098098ASDJKHkmKJHmnnbvv===",
"RefreshTokenValidityInDays": 7
},
"EmailConfiguration": {
"From": "xxx",
"SmtpServer": "xxx",
"Port": 587,
"UserName": "xxx",
"Password": "xxx"
},
"Authentication": {
"GoogleWebClientId": "xxx",
"GoogleAndroidClientId": "xxx",
"GoogleIOSClientId": "xxx",
"ClientSecret": "xxx"
}
}
这是该服务的 systemd 文件:
[Unit]
Description=SoriooWebApi
[Service]
WorkingDirectory /home/app/SoriooWebApi
ExecStart=dotnet /home/app/SoriooWebApi/Retyoo.WebApi.dll
SyslogIdentifier=SoriooWebApi
User=ubuntu
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
当我在本地主机上发布 api 时,我没有错误,我也可以在发布的文件夹中看到 appsettings.json、appsettings.Production.json 文件。我实在找不到问题所在
那是我的错误,我已经研究了这个问题两天了,终于找到了问题所在。问题是在服务文件第 5 行(即“WorkingDirectory”)上添加“=”。我的发现是一个巧合,因为当我尝试使用“journalctl”命令检查服务状态时,出现了一条警告,指出第 5 行缺少“=”,但这是我的第 40 次检查,最后我看到了该消息。添加了“=”,现在它可以工作了...