diff --git a/.gitignore b/.gitignore index 2400df5..0502adf 100755 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ - # 기본 파일 및 폴더 제외 *.log *.env @@ -55,6 +54,11 @@ obj/ # Blazor 관련 **/wwwroot/_framework/ +./wwwroot +**/wwwroot +**/publish +./publish + # Docker 관련 docker-compose.override.yml @@ -62,4 +66,68 @@ Dockerfile # 기타 캐시 파일 **/*.cache -**/*.tmp \ No newline at end of file +**/*.tmp# 특정 환경에 따라 추가 + /private/ + /publish/ + /bin/ + /obj/ + + ./private/ + ./privacy/ + ./publish/ + ./bin/ + + + + + # 기본 파일 및 폴더 제외 + *.log + *.env + *.bak + *.tmp + *.swp + + # macOS 관련 파일 제외 + ._ + ._* + .DS_Store + .AppleDouble + .LSOverride + .Spotlight-V100 + .Trashes + + # Windows 관련 + Thumbs.db + ehthumbs.db + desktop.ini + + # Visual Studio 관련 + .vscode/ + .vs/ + *.suo + *.user + *.userosscache + *.sln.docstates + + # Rider 관련 + .idea/ + *.sln.iml + + # .NET 관련 + bin/ + obj/ + *.pdb + *.dll + *.exe + *.nuget/ + + # Blazor 관련 + **/wwwroot/_framework/ + + # Docker 관련 + docker-compose.override.yml + Dockerfile + + # 기타 캐시 파일 + **/*.cache + **/*.tmp \ No newline at end of file diff --git a/Program.cs b/Program.cs index 5fa9a9c..c80148c 100644 --- a/Program.cs +++ b/Program.cs @@ -4,6 +4,7 @@ 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; @@ -23,6 +24,7 @@ using Back.Program.Services.V1; using Back.Program.Services.V1.Interfaces; + var builder = WebApplication.CreateBuilder(args); @@ -174,6 +176,7 @@ else ///// ===== builder 설정 부 ===== ///// var app = builder.Build(); +string staticRoot; if (app.Environment.IsDevelopment()) { @@ -181,11 +184,13 @@ if (app.Environment.IsDevelopment()) // app.UseSwaggerUI(); app.UseCustomSwaggerUI(); app.UseDeveloperExceptionPage(); // 좀더 자세한 예외 정보 제공 + staticRoot = Path.Combine(Directory.GetCurrentDirectory(), "publish", "debug", "wwwroot"); } else { app.UseExceptionHandler("/error"); app.UseHsts(); + staticRoot = Path.Combine(Directory.GetCurrentDirectory(), "publish", "release", "wwwroot"); } // 로컬 테스트 위한 부분 (올릴떄는 켜두기) @@ -198,14 +203,31 @@ app.UseMiddleware( (object)new string[] { "iOS_AM_Connect_Key", "And_AM_Connect_Key", "Web_AM_Connect_Key" } ); +// app.UseBlazorFrameworkFiles(); +// app.UseStaticFiles(); + +app.UseStaticFiles(new StaticFileOptions +{ + FileProvider = new PhysicalFileProvider(staticRoot), + RequestPath = "" +}); + + + + app.UseRouting(); app.UseCors("CorsPolicy"); app.UseAuthorization(); app.UseWebSockets(); + app.UseEndpoints(end => { ControllerEndpointRouteBuilderExtensions.MapControllers(end); + + // 프론트 테스트 위한 부분 + end.MapFallbackToFile("index.html"); + end.MapHub("/chatHub"); }); diff --git a/Program/Common/Auth/APIHeaderMiddleware.cs b/Program/Common/Auth/APIHeaderMiddleware.cs index 6b268a8..a4a26fb 100644 --- a/Program/Common/Auth/APIHeaderMiddleware.cs +++ b/Program/Common/Auth/APIHeaderMiddleware.cs @@ -7,12 +7,11 @@ namespace Back.Program.Common.Auth /// public class APIHeaderMiddleware { - private readonly RequestDelegate _next; private readonly string[] _headerNames; // private readonly IHeaderConfig _headerConfig; - public APIHeaderMiddleware(RequestDelegate next, string[] headerNames)//, IHeaderConfig headerConfig) + public APIHeaderMiddleware(RequestDelegate next, string[] headerNames) //, IHeaderConfig headerConfig) { _next = next; _headerNames = headerNames; @@ -25,36 +24,46 @@ namespace Back.Program.Common.Auth await _next(context); return; } - - // Scoped 사용해서 값 가져오는 곳임 - var headerConfig = context.RequestServices.GetRequiredService(); - - bool valid = false; - foreach (var header in _headerNames) + // 정적 파일 요청은 미들웨어 건너뜀 + var path = context.Request.Path.Value; + if (path != null && (path.StartsWith("/api"))) { - /// context.Request.Headers.TryGetValue(header, out var headerValue) - /// header 를 찾는데 header - if (context.Request.Headers.TryGetValue(header, out var headerValue) && - !string.IsNullOrWhiteSpace(headerValue)) + // Scoped 사용해서 값 가져오는 곳임 + var headerConfig = context.RequestServices.GetRequiredService(); + + bool valid = false; + + foreach (var header in _headerNames) { - var keyName = await headerConfig.GetExpectedHeaderValueAsync(headerValue); - if (keyName != string.Empty) + /// context.Request.Headers.TryGetValue(header, out var headerValue) + /// header 를 찾는데 header + if (context.Request.Headers.TryGetValue(header, out var headerValue) && + !string.IsNullOrWhiteSpace(headerValue)) { - valid = true; - break; + var keyName = await headerConfig.GetExpectedHeaderValueAsync(headerValue); + if (keyName != string.Empty) + { + valid = true; + break; + } } } + + if (!valid) + { + context.Response.StatusCode = StatusCodes.Status401Unauthorized; + await context.Response.WriteAsync($"Invalid header value"); + return; + } + + await _next(context); } - if (!valid) { - context.Response.StatusCode = StatusCodes.Status401Unauthorized; - await context.Response.WriteAsync($"Invalid header value"); + await _next(context); return; } - - await _next(context); } } } \ No newline at end of file diff --git a/Program/Common/Chat/ChatHub.cs b/Program/Common/Chat/ChatHub.cs index 6e8a9c0..138f25c 100644 --- a/Program/Common/Chat/ChatHub.cs +++ b/Program/Common/Chat/ChatHub.cs @@ -1,42 +1,57 @@ +using Back.Program.Services.V1.Interfaces; using Microsoft.AspNetCore.SignalR; -namespace Back.Program.Common.Chat +namespace Back.Program.Common.Chat; + +public class ChatHub : Hub { - public class ChatHub : Hub + private readonly ILogger _logger; + private readonly IChatService _chatService; + + public ChatHub(ILogger logger, IChatService chatService) { - // 클라이언트에서 메시지를 보내면 모든 사용자에게 전송 - public async Task SendMessage(string user, string message) - { - Console.WriteLine($"Message received: {user}: {message}"); - await Clients.All.SendAsync("ReceiveMessage", user, message); - - } - - // 특정 사용자에게 메시지를 보냄 - public async Task SendMessageToUser(string connectionId, string message) - { - await Clients.Client(connectionId).SendAsync("ReceiveMessage", message); - } - - // 클라이언트가 연결될 때 호출 - public override async Task OnConnectedAsync() - { - await Clients.Caller.SendAsync("ReceiveMessage", "System", $"Welcome! Your ID: {Context.ConnectionId}"); - Console.WriteLine("OnConnectedAsync"); - await base.OnConnectedAsync(); - } - - // 클라이언트가 연결 해제될 때 호출 - public override async Task OnDisconnectedAsync(Exception? exception) - { - await Clients.All.SendAsync("ReceiveMessage", "System", $"{Context.ConnectionId} disconnected"); - Console.WriteLine("OnDisconnectedAsync"); - await base.OnDisconnectedAsync(exception); - } + _logger = logger; + _chatService = chatService; } -} - -/* -*/ \ No newline at end of file + // 클라이언트에서 메시지를 보내면 모든 사용자에게 전송 + public async Task SendMessage(string user, string message) + { + Console.WriteLine($"Message received: {user}: {message}"); + await Clients.All.SendAsync("ReceiveMessage", user, message); + } + + // 특정 사용자에게 메시지를 보냄 + public async Task SendMessageToUser(string connectionId, string message) + { + await Clients.Client(connectionId).SendAsync("ReceiveMessage", message); + } + + // 클라이언트가 연결될 때 호출 + public override async Task OnConnectedAsync() + { + await Clients.Caller.SendAsync("ReceiveMessage", "System", $"Welcome! Your ID: {Context.ConnectionId}"); + Console.WriteLine("OnConnectedAsync"); + await base.OnConnectedAsync(); + } + + // 클라이언트가 연결 해제될 때 호출 + public override async Task OnDisconnectedAsync(Exception? exception) + { + await Clients.All.SendAsync("ReceiveMessage", "System", $"{Context.ConnectionId} disconnected"); + Console.WriteLine("OnDisconnectedAsync"); + await base.OnDisconnectedAsync(exception); + } + + + public async Task JoinRoom(string cid) + { + await Groups.AddToGroupAsync(Context.ConnectionId, cid); + } + + public async Task JoinGroup(string cid, string groupName) + { + await Groups.AddToGroupAsync(Context.ConnectionId, groupName); + } +} \ No newline at end of file diff --git a/Program/Controllers/V1/ChatController.cs b/Program/Controllers/V1/ChatController.cs new file mode 100644 index 0000000..0fcd9ed --- /dev/null +++ b/Program/Controllers/V1/ChatController.cs @@ -0,0 +1,6 @@ +namespace Back.Program.Controllers.V1; + +public class ChatController +{ + +} \ No newline at end of file diff --git a/Program/Services/V1/ChatService.cs b/Program/Services/V1/ChatService.cs new file mode 100644 index 0000000..b06d1a5 --- /dev/null +++ b/Program/Services/V1/ChatService.cs @@ -0,0 +1,8 @@ +using Back.Program.Services.V1.Interfaces; + +namespace Back.Program.Services.V1; + +public class ChatService: IChatService +{ + +} \ No newline at end of file diff --git a/Program/Services/V1/Interfaces/IChatService.cs b/Program/Services/V1/Interfaces/IChatService.cs new file mode 100644 index 0000000..8959c4c --- /dev/null +++ b/Program/Services/V1/Interfaces/IChatService.cs @@ -0,0 +1,6 @@ +namespace Back.Program.Services.V1.Interfaces; + +public interface IChatService +{ + +} \ No newline at end of file