diff --git a/Back.csproj b/Back.csproj
index f591412..b289ad8 100644
--- a/Back.csproj
+++ b/Back.csproj
@@ -18,5 +18,9 @@
+
+
+
+
diff --git a/Program.cs b/Program.cs
index 468caf6..5fa9a9c 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,6 +1,5 @@
using Pomelo.EntityFrameworkCore;
using System.Text;
-using AcaMate.Common.Chat;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
@@ -10,13 +9,18 @@ using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Security.Cryptography.X509Certificates;
using System.Text.Json;
-
-using AcaMate.Common.Models;
-using AcaMate.V1.Services;
-using AcaMate.Common.Data;
-using AcaMate.Common.Token;
-using AcaMate.V1.Controllers;
-using AcaMate.V1.Models;
+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;
var builder = WebApplication.CreateBuilder(args);
@@ -24,6 +28,8 @@ var builder = WebApplication.CreateBuilder(args);
// DB 설정부 시작
builder.Configuration.AddJsonFile("private/dbSetting.json", optional: true, reloadOnChange: true);
+
+builder.Services.AddHttpContextAccessor();
// var connectionString = builder.Configuration.GetConnectionString("MariaDbConnection");
// builder.Services.AddDbContext(options => options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString)));
builder.Services.AddDbContext(optionsAction: (serviceProvider, options) =>
@@ -38,7 +44,7 @@ builder.Services.AddDbContext(optionsAction: (serviceProvider, opt
options.UseMySql(baseConnectionString, ServerVersion.AutoDetect(baseConnectionString));
});
-builder.Services.AddHttpContextAccessor();
+
// DB 설정부 끝
@@ -84,7 +90,7 @@ builder.Services.AddAuthentication(options =>
builder.Services.Configure(builder.Configuration.GetSection("PushFileSetting"));
// HttpClientFactory를 이용한 ApnsPushService 등록 (핸들러에 인증서 추가)
-builder.Services.AddHttpClient(client =>
+builder.Services.AddHttpClient(client =>
{
var settings = builder.Configuration.GetSection("PushFileSetting").Get();
client.BaseAddress = new Uri(settings.uri);
@@ -113,9 +119,19 @@ builder.Services.AddHostedService();
builder.Services.AddControllers();
// 여기다가 API 있는 컨트롤러들 AddScoped 하면 되는건가?
-builder.Services.AddScoped();
-builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
+
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+
+builder.Services.AddScoped();
+builder.Services.AddScoped();
+
+// builder.Services.AddScoped();
+builder.Services.AddScoped();
// builder.Services.AddScoped(); //
// builder.Services.AddScoped();
@@ -151,10 +167,6 @@ else
builder.Logging.SetMinimumLevel(LogLevel.Warning);
}
-//헤더 부분
-builder.Services.AddScoped();
-
-
// 로컬 테스트 위한 부분 (올릴때는 꺼두기)
// builder.WebHost.UseUrls("http://0.0.0.0:5144");
@@ -179,21 +191,21 @@ else
// 로컬 테스트 위한 부분 (올릴떄는 켜두기)
app.UseHttpsRedirection();
+//예외처리 미들웨어 부분
+app.UseMiddleware();
// 헤더 미들웨어 부분
-app.UseMiddleware((object)new string[] { "iOS_AM_Connect_Key", "And_AM_Connect_Key", "Web_AM_Connect_Key" });
-// app.UseMiddleware("X-MyHeader");
-
+app.UseMiddleware(
+ (object)new string[] { "iOS_AM_Connect_Key", "And_AM_Connect_Key", "Web_AM_Connect_Key" }
+ );
app.UseRouting();
-// app.MapControllers();
-
app.UseCors("CorsPolicy");
app.UseAuthorization();
app.UseWebSockets();
app.UseEndpoints(end =>
{
- end.MapControllers();
+ ControllerEndpointRouteBuilderExtensions.MapControllers(end);
end.MapHub("/chatHub");
});
diff --git a/Program/Common/Auth/APIHeaderMiddleware.cs b/Program/Common/Auth/APIHeaderMiddleware.cs
index 1983e08..6b268a8 100644
--- a/Program/Common/Auth/APIHeaderMiddleware.cs
+++ b/Program/Common/Auth/APIHeaderMiddleware.cs
@@ -1,86 +1,60 @@
-using System.Threading.Tasks;
-using AcaMate.Common.Data;
-using Microsoft.AspNetCore.Http;
+using Back.Program.Common.Auth.Interface;
+using Back.Program.Common.Data;
using Microsoft.EntityFrameworkCore;
-namespace AcaMate.Common.Token;
-
-public interface IHeaderConfig
+namespace Back.Program.Common.Auth
{
- Task GetExpectedHeaderValueAsync(string headerName);
-}
-
-///
-/// DB에서 헤더 키값 찾아서 그 밸류 값 빼오기 위해서 사용
-///
-public class HeaderConfigRepository : IHeaderConfig
-{
- private readonly AppDbContext _dbContext;
-
- public HeaderConfigRepository(AppDbContext dbContext)
+ ///
+ public class APIHeaderMiddleware
{
- _dbContext = dbContext;
- }
-
- public async Task GetExpectedHeaderValueAsync(string headerValue)
- {
- var config = await _dbContext.APIHeader
- .FirstOrDefaultAsync(h => h.h_value == headerValue);
- return config?.h_key ?? string.Empty;
- }
-}
+ private readonly RequestDelegate _next;
+ private readonly string[] _headerNames;
+ // private readonly IHeaderConfig _headerConfig;
-public class APIHeaderMiddleware
-{
-
- private readonly RequestDelegate _next;
- private readonly string[] _headerNames;
- // private readonly IHeaderConfig _headerConfig;
-
- public APIHeaderMiddleware(RequestDelegate next, string[] headerNames)//, IHeaderConfig headerConfig)
- {
- _next = next;
- _headerNames = headerNames;
- }
-
- public async Task Invoke(HttpContext context)
- {
-
- if (context.Request.Path.Equals("/api/v1/in/app", StringComparison.OrdinalIgnoreCase))
+ public APIHeaderMiddleware(RequestDelegate next, string[] headerNames)//, IHeaderConfig headerConfig)
{
- await _next(context);
- return;
+ _next = next;
+ _headerNames = headerNames;
}
-
- // Scoped 사용해서 값 가져오는 곳임
- var headerConfig = context.RequestServices.GetRequiredService();
-
- bool valid = false;
- foreach (var header in _headerNames)
+ public async Task Invoke(HttpContext context)
{
- /// context.Request.Headers.TryGetValue(header, out var headerValue)
- /// header 를 찾는데 header
- if (context.Request.Headers.TryGetValue(header, out var headerValue) &&
- !string.IsNullOrWhiteSpace(headerValue))
+ if (context.Request.Path.Equals("/api/v1/in/app", StringComparison.OrdinalIgnoreCase))
{
- var keyName = await headerConfig.GetExpectedHeaderValueAsync(headerValue);
- if (keyName != string.Empty)
+ await _next(context);
+ return;
+ }
+
+ // Scoped 사용해서 값 가져오는 곳임
+ var headerConfig = context.RequestServices.GetRequiredService();
+
+ bool valid = false;
+
+ foreach (var header in _headerNames)
+ {
+ /// 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;
- }
+ if (!valid)
+ {
+ context.Response.StatusCode = StatusCodes.Status401Unauthorized;
+ await context.Response.WriteAsync($"Invalid header value");
+ return;
+ }
- await _next(context);
+ await _next(context);
+ }
}
}
\ No newline at end of file
diff --git a/Program/Common/Auth/HeaderConfigRepository.cs b/Program/Common/Auth/HeaderConfigRepository.cs
new file mode 100644
index 0000000..91a045b
--- /dev/null
+++ b/Program/Common/Auth/HeaderConfigRepository.cs
@@ -0,0 +1,27 @@
+using Back.Program.Common.Auth.Interface;
+using Back.Program.Common.Data;
+using Microsoft.EntityFrameworkCore;
+
+namespace Back.Program.Common.Auth
+{
+ ///
+ /// DB에서 헤더 키값 찾아서 그 밸류 값 빼오기 위해서 사용
+ ///
+ public class HeaderConfigRepository : IHeaderConfig
+ {
+ private readonly AppDbContext _dbContext;
+
+ public HeaderConfigRepository(AppDbContext dbContext)
+ {
+ _dbContext = dbContext;
+ }
+
+ public async Task GetExpectedHeaderValueAsync(string headerValue)
+ {
+ var config = await _dbContext.APIHeader
+ .FirstOrDefaultAsync(h => h.h_value == headerValue);
+ return config?.h_key ?? string.Empty;
+ }
+
+ }
+}
diff --git a/Program/Common/Auth/Interface/IHeaderConfig.cs b/Program/Common/Auth/Interface/IHeaderConfig.cs
new file mode 100644
index 0000000..04e5587
--- /dev/null
+++ b/Program/Common/Auth/Interface/IHeaderConfig.cs
@@ -0,0 +1,7 @@
+namespace Back.Program.Common.Auth.Interface
+{
+ public interface IHeaderConfig
+ {
+ Task GetExpectedHeaderValueAsync(string headerName);
+ }
+}
diff --git a/Program/Common/Auth/JwtTokenService.cs b/Program/Common/Auth/JwtTokenService.cs
index 909fb9e..caa0e27 100644
--- a/Program/Common/Auth/JwtTokenService.cs
+++ b/Program/Common/Auth/JwtTokenService.cs
@@ -1,109 +1,107 @@
-using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
-using System.Text;
-using System.Collections.Generic;
-using AcaMate.Common.Models;
-using Microsoft.IdentityModel.Tokens;
-using Microsoft.Extensions.Options;
-using Microsoft.AspNetCore.Authentication;
-using Microsoft.AspNetCore.Mvc;
-
-
using System.Security.Cryptography;
+using System.Text;
+using Back.Program.Common.Model;
+using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Tokens;
-namespace AcaMate.Common.Token;
-
-public class JwtTokenService
+namespace Back.Program.Common.Auth
{
- private readonly JwtSettings _jwtSettings;
- private readonly ILogger _logger;
-
- public JwtTokenService(IOptions jwtSettings, ILogger logger)
- {
- _jwtSettings = jwtSettings.Value;
- _logger = logger;
- }
-
- public string GenerateJwtToken(string jwtKey)//, string role)
- {
- // 1. 클레임(Claim) 설정 - 필요에 따라 추가 정보도 포함
- var claims = new List
- {
- // 토큰 주체(sub) 생성을 위해 값으로 uid를 사용함 : 토큰이 대표하는 고유 식별자
- new Claim(JwtRegisteredClaimNames.Sub, jwtKey),
- // Jti 는 토큰 식별자로 토큰의 고유 ID 이다.
- new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
- // jwt 토큰이 가지는 권한
- // new Claim(ClaimTypes.Role, role),
- // 추가 클레임 예: new Claim(ClaimTypes.Role, "Admin")
- };
-
- // 2. 비밀 키와 SigningCredentials 생성
- var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
- var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
-
- // 3. 토큰 생성 (Issuer, Audience, 만료 시간, 클레임, 서명 정보 포함)
- var token = new JwtSecurityToken(
- issuer: _jwtSettings.Issuer,
- audience: _jwtSettings.Audience,
- claims: claims,
- expires: DateTime.Now.AddMinutes(_jwtSettings.ExpiryMinutes),
- signingCredentials: credentials
- );
-
- // 4. 토큰 객체를 문자열로 변환하여 반환
- return new JwtSecurityTokenHandler().WriteToken(token);
- }
-
- public RefreshToken GenerateRefreshToken(string uid)
- {
- var randomNumber = new byte[32]; // 256비트
- using (var rng = RandomNumberGenerator.Create())
- {
- rng.GetBytes(randomNumber);
- }
-
- return new RefreshToken()
- {
- uid = uid,
- refresh_token = Convert.ToBase64String(randomNumber),
- create_Date = DateTime.UtcNow,
- expire_date = DateTime.UtcNow.AddDays(_jwtSettings.RefreshTokenExpiryDays)
-
- };
- }
-
-
///
- /// 여기는 엑세스 토큰의 확인을 위한 jwt 서비스 내의 인증 메서드
+ /// 사용자의 정보를 바탕으로 JWT 생성
///
- public async Task ValidateToken(string token)
+ public class JwtTokenService
{
- if (string.IsNullOrWhiteSpace(token)) return null;
- var tokenHandler = new JwtSecurityTokenHandler();
+ private readonly JwtSettings _jwtSettings;
+ private readonly ILogger _logger;
- try
+ public JwtTokenService(IOptions jwtSettings, ILogger logger)
{
- var key = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey);
- var validationParameters = new TokenValidationParameters
- {
- ValidateIssuerSigningKey = true,
- IssuerSigningKey = new SymmetricSecurityKey(key),
- ValidateIssuer = true,
- ValidIssuer = _jwtSettings.Issuer,
- ValidateAudience = true,
- ValidAudience = _jwtSettings.Audience,
- ValidateLifetime = true,
- ClockSkew = TimeSpan.FromMinutes(_jwtSettings.ClockSkewMinutes)
- };
- var principal = tokenHandler.ValidateToken(token, validationParameters, out var securityToken);
- return principal;
+ _jwtSettings = jwtSettings.Value;
+ _logger = logger;
}
- catch (Exception ex)
+
+ public string GenerateJwtToken(string jwtKey)//, string role)
{
- _logger.LogError($"엑세스 토큰 오류: {ex.Message}");
- return null;
+ // 1. 클레임(Claim) 설정 - 필요에 따라 추가 정보도 포함
+ var claims = new List
+ {
+ // 토큰 주체(sub) 생성을 위해 값으로 uid를 사용함 : 토큰이 대표하는 고유 식별자
+ new Claim(JwtRegisteredClaimNames.Sub, jwtKey),
+ // Jti 는 토큰 식별자로 토큰의 고유 ID 이다.
+ new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
+ // jwt 토큰이 가지는 권한
+ // new Claim(ClaimTypes.Role, role),
+ // 추가 클레임 예: new Claim(ClaimTypes.Role, "Admin")
+ };
+
+ // 2. 비밀 키와 SigningCredentials 생성
+ var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
+ var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
+
+ // 3. 토큰 생성 (Issuer, Audience, 만료 시간, 클레임, 서명 정보 포함)
+ var token = new JwtSecurityToken(
+ issuer: _jwtSettings.Issuer,
+ audience: _jwtSettings.Audience,
+ claims: claims,
+ expires: DateTime.Now.AddMinutes(_jwtSettings.ExpiryMinutes),
+ signingCredentials: credentials
+ );
+
+ // 4. 토큰 객체를 문자열로 변환하여 반환
+ return new JwtSecurityTokenHandler().WriteToken(token);
+ }
+
+ public RefreshToken GenerateRefreshToken(string uid)
+ {
+ var randomNumber = new byte[32]; // 256비트
+ using (var rng = RandomNumberGenerator.Create())
+ {
+ rng.GetBytes(randomNumber);
+ }
+
+ return new RefreshToken()
+ {
+ uid = uid,
+ refresh_token = Convert.ToBase64String(randomNumber),
+ create_Date = DateTime.UtcNow,
+ expire_date = DateTime.UtcNow.AddDays(_jwtSettings.RefreshTokenExpiryDays)
+
+ };
+ }
+
+
+ ///
+ /// 여기는 엑세스 토큰의 확인을 위한 jwt 서비스 내의 인증 메서드
+ ///
+ public async Task ValidateToken(string token)
+ {
+ if (string.IsNullOrWhiteSpace(token)) return null;
+ var tokenHandler = new JwtSecurityTokenHandler();
+
+ try
+ {
+ var key = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey);
+ var validationParameters = new TokenValidationParameters
+ {
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = new SymmetricSecurityKey(key),
+ ValidateIssuer = true,
+ ValidIssuer = _jwtSettings.Issuer,
+ ValidateAudience = true,
+ ValidAudience = _jwtSettings.Audience,
+ ValidateLifetime = true,
+ ClockSkew = TimeSpan.FromMinutes(_jwtSettings.ClockSkewMinutes)
+ };
+ var principal = tokenHandler.ValidateToken(token, validationParameters, out var securityToken);
+ return principal;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"엑세스 토큰 오류: {ex.Message}");
+ return null;
+ }
}
}
}
\ No newline at end of file
diff --git a/Program/Common/Chat/ChatHub.cs b/Program/Common/Chat/ChatHub.cs
index 9841c96..6e8a9c0 100644
--- a/Program/Common/Chat/ChatHub.cs
+++ b/Program/Common/Chat/ChatHub.cs
@@ -1,37 +1,42 @@
using Microsoft.AspNetCore.SignalR;
-using System.Threading.Tasks;
-namespace AcaMate.Common.Chat;
-
-public class ChatHub : Hub
+namespace Back.Program.Common.Chat
{
- // 클라이언트에서 메시지를 보내면 모든 사용자에게 전송
- public async Task SendMessage(string user, string message)
+ public class ChatHub : Hub
{
- Console.WriteLine($"Message received: {user}: {message}");
- await Clients.All.SendAsync("ReceiveMessage", user, message);
+ // 클라이언트에서 메시지를 보내면 모든 사용자에게 전송
+ 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 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 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 override async Task OnDisconnectedAsync(Exception? exception)
+ {
+ await Clients.All.SendAsync("ReceiveMessage", "System", $"{Context.ConnectionId} disconnected");
+ Console.WriteLine("OnDisconnectedAsync");
+ await base.OnDisconnectedAsync(exception);
+ }
}
-}
\ No newline at end of file
+}
+
+/*
+
+
+*/
\ No newline at end of file
diff --git a/Program/Common/Data/AppDbContext.cs b/Program/Common/Data/AppDbContext.cs
index 17b4e16..92b653f 100644
--- a/Program/Common/Data/AppDbContext.cs
+++ b/Program/Common/Data/AppDbContext.cs
@@ -1,56 +1,60 @@
-using AcaMate.Common.Models;
+using Back.Program.Common.Model;
+using Back.Program.Models.Entities;
using Microsoft.EntityFrameworkCore;
-using AcaMate.V1.Models;
-using Version = AcaMate.V1.Models.Version;
+using Version = Back.Program.Models.Entities.Version;
-namespace AcaMate.Common.Data;
-//database=AcaMate;
-public class AppDbContext: DbContext
+namespace Back.Program.Common.Data
{
- public AppDbContext(DbContextOptions options) : base(options)
+ //database=AcaMate;
+ public class AppDbContext: DbContext
{
- }
+ public AppDbContext(DbContextOptions options) : base(options)
+ {
+ }
- //MARK: API
- public DbSet APIHeader { get; set; }
+ //MARK: API
+ public DbSet APIHeader { get; set; }
- //MARK: Program
- public DbSet Version { get; set; }
- public DbSet Academy { get; set; }
- public DbSet RefreshTokens { get; set; }
+ //MARK: Program
+ public DbSet Version { get; set; }
+ public DbSet Academy { get; set; }
+ public DbSet RefreshToken { get; set; }
- //MARK: USER
- public DbSet Login { get; set; }
- public DbSet UserAcademy { get; set; }
- public DbSet User { get; set; }
- public DbSet Permission { get; set; }
- // public DbSet Token { get; set; }
- public DbSet Location { get; set; }
- public DbSet Contact { get; set; }
+ //MARK: USER
+ public DbSet Login { get; set; }
+ public DbSet UserAcademy { get; set; }
+ public DbSet User { get; set; }
+ public DbSet Permission { get; set; }
+ // public DbSet Token { get; set; }
+ public DbSet Location { get; set; }
+ public DbSet Contact { get; set; }
- //MARK: PUSH
- public DbSet DBPayload { get; set; }
- public DbSet PushCabinet { get; set; }
+ //MARK: PUSH
+ public DbSet DBPayload { get; set; }
+ public DbSet PushCabinet { get; set; }
+ //MARK: CHATTING
+ // public DbSet<>
- //MARK: LOG
- public DbSet LogPush { get; set; }
- public DbSet LogUser { get; set; }
- public DbSet LogProject { get; set; }
+ //MARK: LOG
+ public DbSet LogPush { get; set; }
+ public DbSet LogUser { get; set; }
+ public DbSet LogProject { get; set; }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.Entity()
- .HasKey(ua => new { ua.uid, ua.bid });
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Entity()
+ .HasKey(ua => new { ua.uid, ua.bid });
- // modelBuilder.Entity()
- // .HasKey(c => new { c.uid, c.bid, c.pid });
+ // modelBuilder.Entity()
+ // .HasKey(c => new { c.uid, c.bid, c.pid });
- modelBuilder.Entity()
- .HasKey(p => new { p.bid, p.pid });
+ modelBuilder.Entity()
+ .HasKey(p => new { p.bid, p.pid });
- // modelBuilder.Entity().HasNoKey();
+ // modelBuilder.Entity().HasNoKey();
+ }
}
}
\ No newline at end of file
diff --git a/Program/Common/Middleware/ExceptionMiddleware.cs b/Program/Common/Middleware/ExceptionMiddleware.cs
new file mode 100644
index 0000000..e1b1d58
--- /dev/null
+++ b/Program/Common/Middleware/ExceptionMiddleware.cs
@@ -0,0 +1,49 @@
+using System.Text.Json;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using System.Threading.Tasks;
+using Back.Program.Common.Model;
+
+namespace Back.Program.Common.Middleware;
+
+public class ExceptionMiddleware
+{
+ private readonly RequestDelegate _next;
+ private readonly ILogger _logger;
+
+ public ExceptionMiddleware(RequestDelegate next, ILogger logger)
+ {
+ _next = next;
+ _logger = logger;
+ }
+
+ public async Task Invoke(HttpContext context)
+ {
+ try
+ {
+ await _next(context); // 다음 미들웨어 호출
+ }
+ catch (AcaException ex)
+ {
+ _logger.LogWarning(ex, $"예외 발생 : {ex.Message}");
+ // 400 : 이건 개발자가 직접 던지는 비즈니스 로직에 대한 예외 == 클라이언트의 오류
+ context.Response.StatusCode = ex.HttpStatus;
+ context.Response.ContentType = "application/json; charset=utf-8";
+
+ var response = APIResponse.Send(ex.Code, ex.Message, string.Empty);
+ var json = JsonSerializer.Serialize(response);
+ await context.Response.WriteAsync(json);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Unhandled Exception");
+ context.Response.StatusCode = 500;
+
+ var response = APIResponse.InternalSeverError("서버 내부 오류가 발생했습니다.");
+ var json = JsonSerializer.Serialize(response);
+
+ context.Response.ContentType = "application/json; charset=utf-8";
+ await context.Response.WriteAsync(json);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Program/Common/Model/APISetting.cs b/Program/Common/Model/APISetting.cs
index 2836748..d1d4ac3 100644
--- a/Program/Common/Model/APISetting.cs
+++ b/Program/Common/Model/APISetting.cs
@@ -1,17 +1,18 @@
-using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
-namespace AcaMate.Common.Models;
-
-[Table("api_header")]
-public class APIHeader
+namespace Back.Program.Common.Model
{
- [Key]
- public string specific_id { get; set; }
+ [Table("api_header")]
+ public class APIHeader
+ {
+ [Key]
+ public string specific_id { get; set; }
- public DateTime connect_date { get; set; }
- public string h_key { get; set; }
- public string h_value { get; set; }
+ public DateTime connect_date { get; set; }
+ public string h_key { get; set; }
+ public string h_value { get; set; }
+ }
}
/*
diff --git a/Program/Common/Model/AcaException.cs b/Program/Common/Model/AcaException.cs
new file mode 100644
index 0000000..a6d069d
--- /dev/null
+++ b/Program/Common/Model/AcaException.cs
@@ -0,0 +1,25 @@
+using System.ComponentModel;
+
+namespace Back.Program.Common.Model;
+
+public static class ResposeCode
+{
+ public const string Success = "000";
+ public const string InputErr = "100";
+ public const string OutputErr = "200";
+ public const string NetworkErr = "300";
+ public const string UnknownErr = "999";
+}
+public class AcaException : Exception
+{
+ public string Code { get; }
+ public int HttpStatus { get; }
+
+ public AcaException(string code, string message, int httpStatus = 400) : base(message)
+ {
+ this.Code = code;
+ this.HttpStatus = httpStatus;
+ }
+}
+
+
diff --git a/Program/Common/Model/JwtSettings.cs b/Program/Common/Model/JwtSettings.cs
index 5836c3e..ae86424 100644
--- a/Program/Common/Model/JwtSettings.cs
+++ b/Program/Common/Model/JwtSettings.cs
@@ -1,39 +1,41 @@
-using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
-namespace AcaMate.Common.Models;
-
-public class JwtSettings
+namespace Back.Program.Common.Model
{
- public string SecretKey { get; set; }
- public string Issuer { get; set; }
- public string Audience { get; set; }
- public int ExpiryMinutes { get; set; }
- public int ClockSkewMinutes { get; set; }
- public int RefreshTokenExpiryDays { get; set; }
-}
+ public class JwtSettings
+ {
+ public string SecretKey { get; set; }
+ public string Issuer { get; set; }
+ public string Audience { get; set; }
+ public int ExpiryMinutes { get; set; }
+ public int ClockSkewMinutes { get; set; }
+ public int RefreshTokenExpiryDays { get; set; }
+ }
-[Table("refresh_token")]
-public class RefreshToken
-{
- [Key]
- [Required(ErrorMessage = "필수 항목 누락")]
- public string uid { get; set; }
- public string refresh_token { get; set; }
- public DateTime create_Date { get; set; }
- public DateTime expire_date { get; set; }
+ [Table("refresh_token")]
+ public class RefreshToken
+ {
+ [Key]
+ [Required(ErrorMessage = "필수 항목 누락")]
+ public string uid { get; set; }
+ public string refresh_token { get; set; }
+ public DateTime create_Date { get; set; }
+ public DateTime expire_date { get; set; }
- // 이건 로그아웃시에 폐기 시킬예정이니 그떄 변경하는걸로 합시다.
- public DateTime? revoke_Date { get; set; }
+ // 이건 로그아웃시에 폐기 시킬예정이니 그떄 변경하는걸로 합시다.
+ public DateTime? revoke_Date { get; set; }
+ }
+
+ public class ValidateToken
+ {
+ public string token { get; set; }
+ public string refresh { get; set; }
+ public string uid { get; set; }
+ }
}
-public class ValidateToken
-{
- public string token { get; set; }
- public string refresh { get; set; }
- public string uid { get; set; }
-}
/*
"""
토큰 동작 관련
diff --git a/Program/Common/Model/Status.cs b/Program/Common/Model/Status.cs
index 75ab156..bcfc234 100644
--- a/Program/Common/Model/Status.cs
+++ b/Program/Common/Model/Status.cs
@@ -1,73 +1,74 @@
using System.Text.Json;
-namespace AcaMate.Common.Models;
-
-public class APIResponseStatus
+namespace Back.Program.Common.Model
{
- public Status status { get; set; }
- public T? data { get; set; }
+ public class APIResponseStatus
+ {
+ public Status status { get; set; }
+ public T? data { get; set; }
- public string JsonToString()
- {
- return JsonSerializer.Serialize(this);
- }
-}
-
-public class Status
-{
- public string code { get; set; }
- public string message { get; set; }
-
-}
-
-public static class APIResponse
-{
- public static APIResponseStatus Send(string code, string message, T data)
- {
- return new APIResponseStatus
+ public string JsonToString()
{
- status = new Status()
+ return JsonSerializer.Serialize(this);
+ }
+ }
+
+ public class Status
+ {
+ public string code { get; set; }
+ public string message { get; set; }
+
+ }
+
+ public static class APIResponse
+ {
+ public static APIResponseStatus Send(string code, string message, T data)
+ {
+ return new APIResponseStatus
{
- code = code,
- message = message
- },
- data = data
- };
- }
+ status = new Status()
+ {
+ code = code,
+ message = message
+ },
+ data = data
+ };
+ }
- ///
- /// 반환값 없는 API 정상 동작시
- ///
- public static APIResponseStatus Success (){
- return Send("000", "정상", "");
- }
+ ///
+ /// 반환값 없는 API 정상 동작시
+ ///
+ public static APIResponseStatus