CORS(Cross Origin Resource Sharing)
소개
이번 강좌에서는 CORS (Cross Origin Resource Sharing, 원본 간 리소스 공유)에 대해 설명하고, 실제로 이를 구현하는 방법을 데모를 통해 살펴볼 예정입니다.
CORS에 대한 기본적인 정보는 Microsoft의 공식 문서를 참조했습니다.
웹 브라우저는 기본적으로 '동일 출처 정책(Same-Origin Policy)'을 적용하여, 한 도메인에서 로드된 웹 페이지가 다른 도메인의 리소스를 요청하는 것을 제한합니다. 이 정책은 악성 사이트가 사용자 데이터를 읽거나 조작하는 것을 방지합니다. 하지만 때때로 안전하고 허용된 출처에서 API 등의 리소스 요청이 필요할 수 있습니다. 예를 들어, 독립적으로 호스팅되는 Web API가 다른 웹 애플리케이션과 통신해야 할 경우 CORS를 활성화하여 동일 출처 정책을 완화할 수 있습니다.
동일 출처 정책에 대한 보다 자세한 설명은 MDN 웹 문서에서 확인할 수 있습니다:
ASP.NET Core에서의 CORS 설정
기본 CORS 설정
ASP.NET Core에서는 Web API를 통해 데이터를 제공할 때, 다른 도메인의 웹 애플리케이션에서도 해당 데이터에 접근할 수 있도록 CORS를 설정할 수 있습니다. Startup.cs
파일의 ConfigureServices
메서드에서 CORS 정책을 정의하고, Configure
메서드에서 이 정책을 활성화시켜야 합니다.
다음은 모든 요청을 허용하는 CORS 설정 예시입니다:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors("AllowAll");
}
다음 코드조각은 ASP.NET Core 6.0 이상에서 사용됩니다.
// 서비스 등록 영역:
builder.Services.AddCors();
...
// 파이프라인 영역:
app.UseCors(config =>
{
config
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
})
이 설정은 모든 원본(origin), 모든 HTTP 메서드, 모든 헤더를 허용합니다. 이는 개발 초기 단계에서 편리할 수 있지만, 보안상의 이유로 출시 전에는 더 제한적인 정책을 설정하는 것이 좋습니다.
특정 도메인 허용 설정
보다 제한적인 CORS 설정을 위해, 특정 도메인만 요청을 허용하도록 설정할 수 있습니다:
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
{
builder.WithOrigins("https://example.com")
.AllowAnyMethod()
.AllowAnyHeader();
});
});
app.UseCors();
위 코드에서 WithOrigins
메서드를 사용하여 특정 도메인을 명시하며, AllowAnyMethod()
와 AllowAnyHeader()
는 해당 도메인에서 모든 종류의 HTTP 요청과 헤더를 허용하도록 설정합니다.
참고 동영상
"CORS 설정 방법"에 관한 더 자세한 내용을 이해하고자 하신다면, "Web API에 CORS(Cross Origin Resource Sharing) 설정하기"라는 제목의 동영상 강좌를 참조하시기 바랍니다. 이 강좌는 DotNetNote 프로젝트 내 ApiHelloWorldWithValueController.cs
파일을 예로 사용하여 CORS의 구현 방법을 설명합니다.
CORS 설정 방식 종류
CORS 설정을 구현하는 방법은 다양합니다:
- 컨트롤러/액션 단위 설정: 특정 컨트롤러나 액션에만 CORS를 적용하려면
[EnableCors]
어노테이션을 사용합니다. - 전체 프로젝트 설정: 전체 애플리케이션에 걸쳐 CORS를 적용하려면
app.UseCors()
미들웨어를 사용합니다.
ASP.NET Core 프로젝트에 CORS 설정하기
1. 필요한 패키지 추가
ASP.NET Core 프로젝트에 CORS를 설정하기 전에, 필요한 NuGet 패키지를 추가합니다. 대부분의 현대 프로젝트에는 기본적으로 포함되어 있습니다:
Microsoft.AspNetCore.Cors
2. CORS 정책 정의
Startup.cs
파일의 ConfigureServices()
메서드에서 원하는 CORS 정책을 추가합니다. 다음 예시에서는 모든 원본에서 모든 종류의 요청을 허용하는 정책을 설정합니다:
services.AddCors(options =>
{
options.AddPolicy("AllowAnyOrigin", builder =>
{
builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
3. CORS 정책 적용
설정한 CORS 정책을 Startup.cs
파일의 Configure()
메서드에서 활성화합니다:
app.UseCors("AllowAnyOrigin");
4. 특정 컨트롤러에 CORS 적용
특정 API 컨트롤러에서 다음과 같이 EnableCors
어노테이션을 사용하여 CORS를 적용할 수 있습니다:
[Route("api/[controller]")]
[EnableCors("AllowAnyOrigin")]
public class HeroesController : Controller
{
// Controller methods here
}
CORS 설정 다양성
ASP.NET Core에서는 다양한 방식으로 CORS를 설정할 수 있습니다. Startup.cs
파일에 다음과 같은 설정 코드 조각을 참고하십시오:
// CORS 정책을 추가하고, 특정 출처만 허용하는 설정
services.AddCors(options =>
{
options.AddPolicy("EntriesPolicy", builder =>
{
builder.WithOrigins("https://example.com").AllowAnyHeader().AllowAnyMethod();
});
});
// 정책 적용
app.UseCors("EntriesPolicy");
위 설정은 https://example.com
도메인으로부터의 요청만을 허용하도록 CORS 정책을 구성합니다. 이러한 방식으로, 보안을 강화하며 필요에 따라 유연하게 CORS를 설정할 수 있습니다.
ASP.NET Core 8.0에서 CORS를 여러 번 설정하는 방법
1. UseCors
의 호출 제한과 정책 설정
app.UseCors
는 ASP.NET Core의 미들웨어 파이프라인에서 한 번만 호출되어야 합니다. 여러 번 호출하면 마지막에 호출된 UseCors
만 적용되므로, 여러 CORS 정책을 설정하고자 할 때는 하나의 호출에 각 정책을 적용하는 방법을 사용해야 합니다.
그러나, 여러 CORS 정책을 정의한 후, 각 컨트롤러나 엔드포인트에 대해 다른 CORS 정책을 적용할 수 있습니다. 이를 위해서는 각 컨트롤러나 액션 메서드에서 [EnableCors]
속성을 사용해야 합니다.
2. 여러 CORS 정책 정의 및 사용 방법
2.1 Program.cs
에서 여러 CORS 정책 정의
먼저, Program.cs
에서 여러 CORS 정책을 정의합니다. 예를 들어, "AllowAll"과 "AllowSpecificOrigins" 두 가지 정책을 정의할 수 있습니다.
var builder = WebApplication.CreateBuilder(args);
// 여러 CORS 정책을 추가
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAll", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
});
options.AddPolicy("AllowSpecificOrigins", builder =>
{
builder.WithOrigins("https://dotnetnote.com")
.AllowAnyMethod()
.AllowAnyHeader();
});
});
// Add services to the container.
builder.Services.AddControllers();
var app = builder.Build();
// 글로벌 CORS 정책 적용 (예: AllowAll)
app.UseCors("AllowAll");
app.UseAuthorization();
app.MapControllers();
app.Run();
이렇게 하면 두 가지 CORS 정책을 정의하고, 전체 애플리케이션에 "AllowAll" 정책을 적용하게 됩니다.
만약, AllowAll 정책을 UseCors에서만 설정하려면 다음과 같이도 할 수 있습니다. 이 경우에는 AddPolicy를 생략해도 됩니다.
// UseCors에서 AllowAll 설정 적용
app.UseCors(builder =>
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
2.2 특정 엔드포인트에 다른 CORS 정책 적용
특정 컨트롤러나 엔드포인트에 다른 CORS 정책을 적용하려면 [EnableCors]
속성을 사용합니다.
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
[Route("api/[controller]")]
[ApiController]
public class SampleController : ControllerBase
{
// 이 엔드포인트는 AllowSpecificOrigins 정책을 적용
[HttpGet]
[EnableCors("AllowSpecificOrigins")]
public IActionResult Get()
{
return Ok("This endpoint allows specific origins.");
}
// 이 엔드포인트는 글로벌 정책을 따름 (AllowAll)
[HttpPost]
public IActionResult Post()
{
return Ok("This endpoint follows the global AllowAll policy.");
}
}
위 코드에서 [EnableCors("AllowSpecificOrigins")]
속성을 사용하여 특정 엔드포인트에서 "AllowSpecificOrigins" 정책을 적용합니다.
3. 핵심 요점
app.UseCors
는 파이프라인에서 한 번만 호출되어야 합니다.- 여러 CORS 정책을 정의한 후, 글로벌 정책을 적용하거나 특정 엔드포인트에서
[EnableCors]
로 다른 정책을 사용할 수 있습니다. - 특정 엔드포인트에서 CORS를 비활성화하려면
[DisableCors]
속성을 사용할 수 있습니다.
이렇게 하면 애플리케이션의 CORS 설정을 더 세밀하게 제어할 수 있습니다.
ASP.NET Core Web API와 MVC 프로젝트를 이용한 CORS 설정 실습
이 튜토리얼에서는 ASP.NET Core를 사용하여 Web API를 생성하고, 별도의 ASP.NET Core MVC 프로젝트에서 JavaScript fetch()
를 이용해 해당 API를 호출하는 과정을 설명합니다. 이 과정에서 CORS 정책으로 인해 실패하는 상황과 이를 해결하는 방법을 단계별로 살펴보겠습니다.
1. ASP.NET Core Web API 프로젝트 생성
첫 단계로 DotNetNote.Apis
라는 이름의 Web API 프로젝트를 생성합니다. 이 프로젝트는 간단한 데이터를 반환하는 API 엔드포인트를 포함합니다.
dotnet new webapi -n DotNetNote.Apis
ValuesController.cs 파일을 다음과 같이 수정하여 테스트 데이터를 반환하도록 설정합니다:
[ApiController]
[Route("[controller]")]
public class ValuesController : ControllerBase
{
[HttpGet]
public IActionResult Get()
{
return Ok(new string[] { "value1", "value2" });
}
}
2. ASP.NET Core MVC 프로젝트 생성
다음으로, DotNetNote
라는 이름의 ASP.NET Core MVC 프로젝트를 생성합니다. 이 프로젝트에서는 HTML 페이지를 통해 JavaScript fetch()
를 사용하여 Web API를 호출합니다.
dotnet new mvc -n DotNetNote
3. JavaScript fetch()를 사용한 API 호출 실패
MVC 프로젝트의 wwwroot 폴더 내에 index.html
파일을 생성하고, 다음과 같이 작성하여 API를 호출합니다:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test API Call</title>
</head>
<body>
<h1>API Data</h1>
<ul id="data"></ul>
<script>
fetch('http://localhost:5000/values')
.then(response => response.json())
.then(data => {
const list = document.getElementById('data');
data.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
list.appendChild(li);
});
})
.catch(error => console.error('Unable to get items.', error));
</script>
</body>
</html>
이 단계에서는 Web API 프로젝트가 CORS를 허용하지 않으므로, 브라우저는 보안 정책을 위반한다고 판단하여 요청을 차단합니다.
4. Web API 프로젝트에서 CORS 설정
DotNetNote.Apis
프로젝트의 Startup.cs
파일을 수정하여 CORS를 허용하도록 설정합니다:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowSpecificOrigin",
builder => builder.WithOrigins("http://localhost:5002")); // MVC 프로젝트 URL
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
// CORS 정책 사용
app.UseCors("AllowSpecificOrigin");
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
5. JavaScript에서 fetch() 성공
이제 index.html
페이지를 다시 로드하면, CORS 정책에 따라 DotNetNote.Apis
프로젝트에서 API 호출을 성공적으로 수행할 수 있습니다. 이로써, Web API와 MVC 프로젝트 간의 상호작용에서 CORS가 중요한 역할을 하는 것을 확인할 수 있습니다.
이 튜토리얼을 통해 웹 개발에서 CORS 설정의 중요성과 기본적인 구현 방법을 이해하고 실습할 수 있습니다.