forked from AcaMate/AcaMate_API
1. 인가코드 받기 2. 리다이렉트 -> 인가 코드를 엑세스 토큰으로 3. User.Me -> snsID 받아오기 4. DB 에서 snsID 조회 까지 완료
235 lines
8.0 KiB
C#
235 lines
8.0 KiB
C#
using Pomelo.EntityFrameworkCore;
|
|
using System.Text;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Microsoft.AspNetCore.SignalR;
|
|
using Microsoft.Extensions.FileProviders;
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using System.Net.Http;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Text.Json;
|
|
using Back;
|
|
using Back.Program.Common.Auth;
|
|
using Back.Program.Common.Auth.Interface;
|
|
using Back.Program.Common.Chat;
|
|
using Back.Program.Common.Data;
|
|
using Back.Program.Common.Middleware;
|
|
using Back.Program.Common.Model;
|
|
using Back.Program.Models.Entities;
|
|
using Back.Program.Repositories.V1;
|
|
using Back.Program.Repositories.V1.Interfaces;
|
|
using Back.Program.Services.V1;
|
|
using Back.Program.Services.V1.Interfaces;
|
|
|
|
|
|
Boolean isLocal = false;
|
|
// 로컬 테스트 할 때는 이거 키고 아니면 끄기
|
|
// isLocal = true;
|
|
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
|
|
// DB 설정부 시작
|
|
builder.Configuration.AddJsonFile("private/dbSetting.json", optional: true, reloadOnChange: true);
|
|
|
|
builder.Services.AddHttpContextAccessor();
|
|
builder.Services.AddDbContext<AppDbContext>(optionsAction: (serviceProvider, options) =>
|
|
{
|
|
var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
|
|
var dbName = httpContextAccessor.HttpContext?.Request.Query["aca_code"].ToString();
|
|
var baseConnectionString = builder.Configuration.GetConnectionString("MariaDbConnection");
|
|
if (!string.IsNullOrEmpty(dbName))
|
|
{
|
|
baseConnectionString = baseConnectionString.Replace("database=AcaMate", $"database={dbName}");
|
|
}
|
|
|
|
options.UseMySql(baseConnectionString, ServerVersion.AutoDetect(baseConnectionString));
|
|
});
|
|
|
|
// DB 설정부 끝
|
|
|
|
|
|
var dbString = builder.Configuration.GetConnectionString("MariaDbConnection");
|
|
var userString = builder.Configuration.GetConnectionString("DBAccount");
|
|
|
|
// JWT 설정부 시작
|
|
if (builder.Environment.IsDevelopment())
|
|
{
|
|
builder.Configuration.AddJsonFile("private/jwtSetting.Development.json", optional: true, reloadOnChange: true);
|
|
}
|
|
else
|
|
{
|
|
builder.Configuration.AddJsonFile("private/jwtSetting.json", optional: true, reloadOnChange: true);
|
|
}
|
|
|
|
builder.Services.Configure<JwtSettings>(builder.Configuration.GetSection("JwtSettings"));
|
|
|
|
builder.Services.AddAuthentication(options =>
|
|
{
|
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
})
|
|
.AddJwtBearer(options =>
|
|
{
|
|
var jwtSettings = builder.Configuration.GetSection("JwtSettings").Get<JwtSettings>();
|
|
options.TokenValidationParameters = new TokenValidationParameters
|
|
{
|
|
ValidateIssuer = true,
|
|
ValidateAudience = true,
|
|
ValidateLifetime = true,
|
|
ValidateIssuerSigningKey = true,
|
|
ValidIssuer = jwtSettings.Issuer,
|
|
ValidAudience = jwtSettings.Audience,
|
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey)),
|
|
ClockSkew = TimeSpan.FromMinutes(jwtSettings.ClockSkewMinutes)
|
|
};
|
|
});
|
|
// JWT 설정부 끝
|
|
|
|
// PUSH 설정부
|
|
// 설정 바인딩 (appsettings.json의 "ApnsPushService" 섹션)
|
|
builder.Services.Configure<PushFileSetting>(builder.Configuration.GetSection("PushFileSetting"));
|
|
|
|
// HttpClientFactory를 이용한 ApnsPushService 등록 (핸들러에 인증서 추가)
|
|
builder.Services.AddHttpClient<IPushService, PushService>(client =>
|
|
{
|
|
var settings = builder.Configuration.GetSection("PushFileSetting").Get<PushFileSetting>();
|
|
client.BaseAddress = new Uri(settings.uri);
|
|
client.Timeout = TimeSpan.FromSeconds(60);
|
|
})
|
|
.ConfigurePrimaryHttpMessageHandler(() =>
|
|
{
|
|
var config = builder.Configuration.GetSection("PushFileSetting").Get<PushFileSetting>();
|
|
var handler = new HttpClientHandler();
|
|
// p12PWPath 파일에서 비밀번호 읽어오기 (예시: JSON {"Password": "비밀번호"})
|
|
var json = File.ReadAllText(config.p12PWPath);
|
|
var keys = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
|
|
var certificate = new X509Certificate2(config.p12Path, keys["Password"]);
|
|
handler.ClientCertificates.Add(certificate);
|
|
handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
|
|
return handler;
|
|
});
|
|
|
|
// InMemoryPushQueue와 백그라운드 서비스 등록
|
|
builder.Services.AddSingleton<IPushQueue, InMemoryPushQueue>();
|
|
builder.Services.AddHostedService<PushBackgroundService>();
|
|
// PUSH 설정부 끝
|
|
|
|
builder.Services.AddControllers();
|
|
|
|
// ==== SCOPED 으로 등록 할 서비스 ==== //
|
|
// 여기다가 API 있는 컨트롤러들 AddScoped 하면 되는건가?
|
|
builder.Services.AddScoped<JwtTokenService>();
|
|
builder.Services.AddScoped<ILogRepository, LogRepository>();
|
|
builder.Services.AddScoped<IRepositoryService, RepositoryService>();
|
|
builder.Services.AddScoped<IHeaderConfig, HeaderConfigRepository>();
|
|
|
|
builder.Services.AddScoped<IUserService, UserService>();
|
|
builder.Services.AddScoped<IKakaoService, KakaoService>();
|
|
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
|
|
|
builder.Services.AddScoped<IAppService, AppService>();
|
|
builder.Services.AddScoped<IAppRepository, AppRepository>();
|
|
|
|
// builder.Services.AddScoped<IPushService, PushService>();
|
|
builder.Services.AddScoped<IPushRepository, PushRepository>();
|
|
// builder.Services.AddScoped<UserService>(); //
|
|
// builder.Services.AddScoped<UserController>();
|
|
|
|
builder.Services.AddEndpointsApiExplorer();
|
|
|
|
// 스웨거 설정 추가 부분
|
|
// builder.Services.AddSwaggerGen();
|
|
builder.Services.AddCustomSwagger();
|
|
|
|
// SignalR 설정 추가 부분
|
|
builder.Services.AddSignalR();
|
|
builder.Services.AddCors(option =>
|
|
{
|
|
option.AddPolicy("CorsPolicy", builder =>
|
|
{
|
|
builder
|
|
.WithOrigins("https://devacamate.ipstein.myds.me", "https://acamate.ipstein.myds.me") // 특정 도메인만 허용
|
|
.AllowAnyMethod()
|
|
.AllowAnyHeader()
|
|
.AllowCredentials();
|
|
|
|
});
|
|
});
|
|
|
|
// 로그 설정 부분
|
|
builder.Logging.ClearProviders();
|
|
builder.Logging.AddConsole();
|
|
builder.Logging.SetMinimumLevel(builder.Environment.IsDevelopment() ? LogLevel.Trace : LogLevel.Warning);
|
|
|
|
if (isLocal)
|
|
{
|
|
builder.WebHost.UseUrls("http://0.0.0.0:5144");
|
|
}
|
|
else
|
|
{
|
|
builder.WebHost.UseUrls(builder.Environment.IsDevelopment()? "http://0.0.0.0:7004":"http://0.0.0.0:7003");
|
|
}
|
|
|
|
///// ===== builder 설정 부 ===== /////
|
|
|
|
var app = builder.Build();
|
|
|
|
string staticRoot;
|
|
if (isLocal)
|
|
{
|
|
staticRoot = app.Environment.IsDevelopment() ? //"/publish/debug/wwwroot" : "/publish/release/wwwroot" ;
|
|
Path.Combine(Directory.GetCurrentDirectory(), "publish", "debug", "wwwroot") : Path.Combine(Directory.GetCurrentDirectory(), "publish", "release", "wwwroot") ;
|
|
}
|
|
else
|
|
{
|
|
staticRoot = app.Environment.IsDevelopment() ?
|
|
"/src/publish/debug/wwwroot" : "/src/publish/release/wwwroot" ;
|
|
}
|
|
|
|
|
|
if (app.Environment.IsDevelopment())
|
|
{
|
|
app.UseCustomSwaggerUI();
|
|
app.UseDeveloperExceptionPage(); // 좀더 자세한 예외 정보 제공
|
|
}
|
|
else
|
|
{
|
|
app.UseExceptionHandler("/error");
|
|
app.UseHsts();
|
|
}
|
|
|
|
// 로컬 테스트 위한 부분 (올릴떄는 켜두기)
|
|
// app.UseHttpsRedirection();
|
|
|
|
// 헤더 미들웨어 부분
|
|
app.UseMiddleware<APIHeaderMiddleware>
|
|
((object)new string[] { "iOS_AM_Connect_Key", "And_AM_Connect_Key", "Web_AM_Connect_Key" });
|
|
|
|
app.UseStaticFiles(new StaticFileOptions
|
|
{
|
|
FileProvider = new PhysicalFileProvider(staticRoot),
|
|
RequestPath = ""
|
|
});
|
|
|
|
app.UseRouting();
|
|
app.UseCors("CorsPolicy");
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
|
|
app.UseWebSockets();
|
|
Console.WriteLine($"[정적 파일 경로] {staticRoot}");
|
|
app.UseEndpoints(end =>
|
|
{
|
|
ControllerEndpointRouteBuilderExtensions.MapControllers(end);
|
|
end.MapHub<ChatHub>("/chatHub");
|
|
end.MapFallback(context => { return context.Response.SendFileAsync(Path.Combine(staticRoot, "index.html")); });
|
|
});
|
|
|
|
|
|
//예외처리 미들웨어 부분
|
|
app.UseMiddleware<ExceptionMiddleware>();
|
|
|
|
app.Run(); |