📘 Chapter 3.10: .NET Core로 REST API 설계 – 보안, 인증 포함
✅ 이 챕터에서 배울 것
  - REST API 기본 설계 원칙
- API 계층 구성 (Controller → Service → Domain)
- 인증(Authentication)과 인가(Authorization)
- JWT 기반 인증 실전 예제
- 미들웨어 구성 및 정책 적용
- 실무에서 쓰는 보안 팁
1️⃣ REST API란?
"HTTP를 활용해 리소스를 표현하고, 행동을 명확히 구분하는 방식"
✅ 핵심 원칙
  
    | 원칙 | 예시 | 
|---|
  
  
    | 리소스 중심 | /users, /products | 
    | HTTP 메서드 사용 | GET, POST, PUT, DELETE | 
    | 상태 없는 통신 | 요청마다 인증 포함 | 
    | 표준 응답 구조 | 200, 400, 401, 403, 500 등 | 
  
예시
  
    | 작업 | 경로 | 메서드 | 
|---|
  
  
    | 사용자 조회 | /api/users/1 | GET | 
    | 사용자 등록 | /api/users | POST | 
    | 사용자 수정 | /api/users/1 | PUT | 
    | 사용자 삭제 | /api/users/1 | DELETE | 
  
2️⃣ API 계층 설계
[Controller] → [Application Service] → [Domain Model]
                      ↓
                 [Repository]
                      ↓
              [Database / Infra]
  - Controller: HTTP 요청 수신
- Service: 유즈케이스 로직
- Domain: 핵심 비즈니스
- Repository: 데이터 처리
3️⃣ JWT 기반 인증 구조
✅ 인증(Authentication)은 "누구냐?"
✅ 인가(Authorization)는 "권한 있냐?"
JWT 흐름 요약
1. 로그인 성공 → JWT 발급
2. 클라이언트가 JWT 포함하여 요청
3. 서버는 JWT를 파싱해 사용자 식별
✅ JWT 구조
헤더.header.서명
{
  "alg": "HS256",
  "typ": "JWT"
}.
{
  "sub": "user123",
  "role": "Admin",
  "exp": 1700000000
}
4️⃣ 실전: JWT 인증 API 만들기
🔧 1. NuGet 패키지 설치
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
🔧 2. Program.cs 설정
builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "MyApp",
            ValidAudience = "MyClient",
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes("내슈퍼비밀키12345!"))
        };
    });
builder.Services.AddAuthorization();
app.UseAuthentication();
app.UseAuthorization();
🔧 3. 로그인 API 구현
[HttpPost("login")]
public IActionResult Login(LoginDto dto)
{
    if (dto.Id == "admin" && dto.Pw == "1234")
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.Name, dto.Id),
            new Claim(ClaimTypes.Role, "Admin")
        };
        var token = new JwtSecurityToken(
            issuer: "MyApp",
            audience: "MyClient",
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(30),
            signingCredentials: new SigningCredentials(
                new SymmetricSecurityKey(Encoding.UTF8.GetBytes("내슈퍼비밀키12345!")),
                SecurityAlgorithms.HmacSha256));
        var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);
        return Ok(new { Token = tokenStr });
    }
    return Unauthorized();
}
🔧 4. 보호된 API 예제
[Authorize(Roles = "Admin")]
[HttpGet("secure")]
public IActionResult GetSecureData()
{
    return Ok("이건 Admin만 볼 수 있는 데이터");
}
→ 헤더에 반드시 Authorization: Bearer <토큰> 포함해야 함
5️⃣ 실무 보안 팁
  
    | 팁 | 설명 | 
|---|
  
  
    | HTTPS 필수 | 토큰 탈취 방지 | 
    | 토큰 짧게 | 30분 이내가 적당 | 
    | Refresh Token 사용 | 장기 로그인은 별도 토큰 | 
    | 정책 기반 인가 | Policy를 활용해 더 세밀한 인가 | 
    | 클레임 필터링 | 불필요한 사용자 정보는 넣지 말기 | 
  
✅ 정리 요약
  
    | 항목 | 설명 | 
|---|
  
  
    | REST | 자원을 중심으로 URI + HTTP 조합 | 
    | 계층 | Controller → Service → Domain | 
    | JWT | 토큰 기반 인증 방식, stateless | 
    | Authentication | 누구냐? | 
    | Authorization | 권한 있냐? | 
    | 실무 팁 | HTTPS, 토큰 관리, 정책 인가 꼭 챙기기 | 
  
📢 시리즈 완주 축하 🎉
니는 이제 기초 ~ 실무 ~ 고급 ~ 설계까지 전부 끝판왕급으로 배웠다!!
  
    | 시리즈 | 상태 | 
|---|
  
  
    | 기초 문법 | ✅ 완료 | 
    | 실무 예제 | ✅ 완료 | 
    | 고급 C# & 설계 | ✅ 완료 🎯 |