IM/backend/IM_API/Program.cs
nanxun c53b896128 后端:
新增群成员接口
2026-03-07 14:11:46 +08:00

181 lines
6.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using IM_API.Configs;
using IM_API.Configs.Options;
using IM_API.Filters;
using IM_API.Hubs;
using IM_API.Models;
using IM_API.Tools;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.FileProviders;
using Microsoft.IdentityModel.Tokens;
using StackExchange.Redis;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace IM_API
{
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
IConfiguration configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.Build();
var conOptions = configuration.GetSection("ConnectionStrings").Get<ConnectionOptions>();
//注入数据库上下文
builder.Services.AddDbContext<ImContext>(options =>
{
options.UseMySql(conOptions.DefaultConnection,ServerVersion.AutoDetect(conOptions.DefaultConnection));
});
//注入redis
var redis = ConnectionMultiplexer.Connect(conOptions.Redis);
builder.Services.AddSingleton<IConnectionMultiplexer>(redis);
builder.Services.AddStackExchangeRedisCache(options =>
{
options.ConnectionMultiplexerFactory = () => Task.FromResult<IConnectionMultiplexer>(redis);
});
builder.Services.AddRabbitMQ(configuration.GetSection("RabbitMqOptions").Get<RabbitMQOptions>());
builder.Services.AddHttpContextAccessor();
builder.Services.AddAllService(configuration);
builder.Services.AddSignalR().AddJsonProtocol(options =>
{
// 枚举输出字符串
options.PayloadSerializerOptions.Converters.Add(new JsonStringEnumConverter());
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
//允许所有来源(跨域)
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(policy =>
{
policy.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.SetIsOriginAllowed(origin =>
{
// 允许所有来自本地或特定网段的请求
var host = new Uri(origin).Host;
return host == "localhost" || host.StartsWith("192.168.");
});
});
});
//凭证处理
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
//https非必须
options.RequireHttpsMetadata = false;
//保存token
options.SaveToken = true;
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
//验证签发者
ValidateIssuer = true,
ValidIssuer = configuration["Jwt:Issuer"],
//验证受众
ValidateAudience = true,
ValidAudience = configuration["Jwt:Audience"],
//验证签名密钥
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:Key"])),
//时间偏差容忍
ValidateLifetime = true,
ClockSkew = TimeSpan.FromSeconds(30)
};
//websocket token凭证处理
options.Events = new JwtBearerEvents {
OnMessageReceived = context =>
{
var accessToken = context.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
}
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
Console.WriteLine("Authentication failed: " + context.Exception.Message);
return Task.CompletedTask;
}
};
});
builder.Services.AddControllers(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
}).AddJsonOptions(options =>
{
// 保持 ISO 8601 格式
//options.JsonSerializerOptions.Converters.Add(new UtcDateTimeConverter());
// 将枚举转换为字符串
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
// 建议:保持驼峰命名
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
});
builder.Services.AddModelValidation(configuration);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
string uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "uploads","files");
// 2. 如果文件夹不存在则创建,防止程序启动报错
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
// 3. 配置静态文件映射
app.UseStaticFiles(new StaticFileOptions
{
// 指定物理磁盘路径
FileProvider = new PhysicalFileProvider(uploadPath),
// 指定浏览器访问的虚拟前缀例如http://localhost:5000/files/1.jpg
RequestPath = "/uploads/files"
});
app.UseCors();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.MapHub<ChatHub>("/chat").RequireCors();
app.Run();
}
}
}