asp.net core : ASP.NET Core Identity를 사용한 비밀번호 해싱, CSRF 보호, 처리 방법
ASP.NET Core Identity를 사용한 비밀번호 해싱, CSRF 보호, 처리를 위해 form data 를 JSON 형식으로 전송하여 전송 중 비밀번호를 보호하는 코드 샘플이 포함된 예제입니다.
1단계: ASP.NET Core Identity 및 HTTPS 구성하기
Startup.cs 파일에서 ASP.NET Core Identity를 구성하고 보안 통신을 위해 HTTPS를 사용하도록 설정합니다.
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireUppercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequiredLength = 8;
});
// ...
services.AddControllersWithViews(options =>
{
options.Filters.Add(new RequireHttpsAttribute());
})
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = null;
});
// ...
}
2단계: CSRF 보호를 사용하여 등록 action 및 view 만들기
CSRF 보호를 사용하여 사용자 등록에 필요한 action 및 view 를 만듭니다.
[FromBody] 속성을 JObject 매개변수와 함께 사용하여 프레임워크에 JSON 데이터를 JObject 객체에 바인딩하도록 지시합니다. 그런 다음 ToObject<T> 메서드를 사용하여 JObject를 RegisterViewModel 객체로 수동으로 변환할 수 있습니다.
public class AccountController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IAntiforgery _antiforgery;
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IAntiforgery antiforgery)
{
_userManager = userManager;
_signInManager = signInManager;
_antiforgery = antiforgery;
}
[HttpGet]
public IActionResult Register()
{
var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
ViewBag.AntiforgeryToken = tokens.RequestToken;
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register([FromBody] JObject data)
{
if (ModelState.IsValid)
{
var model = data.ToObject<RegisterViewModel>();
var user = new ApplicationUser
{
UserName = model.Username
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return BadRequest(ModelState);
}
}
이렇게 변경하면 JSON 데이터가 RegisterViewModel 개체에 올바르게 바인딩되어 등록 작업에서 사용자 이름과 비밀번호에 액세스할 수 있습니다.
@model RegisterViewModel
<form id="registerForm" asp-action="Register" asp-controller="Account">
<div id="registerError" class="alert alert-danger" style="display: none;"></div>
@Html.AntiForgeryToken()
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="Username" required />
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="Password" required />
</div>
<div class="form-group">
<label for="confirmPassword">Confirm Password:</label>
<input type="password" class="form-control" id="confirmPassword" name="ConfirmPassword" required />
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
<script>
$(function () {
$("#registerForm").submit(function (e) {
e.preventDefault();
var form = $(this);
var url = form.attr("action");
var data = JSON.stringify(form.serializeArray());
$.ajax({
url: url,
type: "POST",
data: data,
headers: {
"RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val(),
"Content-Type": "application/json"
},
success: function (response) {
// Handle success response
},
error: function (xhr) {
// Handle error response
$("#registerError").text(xhr.responseText).show();
}
});
});
});
</script>
이 예제에서는 ASP.NET Core Identity를 사용한 비밀번호 해싱, IAntiforgery 서비스를 사용한 CSRF 보호, HTTPS 통신 적용을 포함했습니다. 이제 등록 작업은 위조 방지 토큰을 생성하고 저장한 다음 @Html.AntiForgeryToken() 헬퍼 메서드를 사용하여 등록 form 에 포함합니다.
form 에 submit 을 위한 AJAX 요청은 CSRF 보호를 위해 request headers(요청 헤더)에 CSRF protection(위변조 방지 토큰) 을 포함합니다. form data 는 form.serializeArray()를 사용하여 serialize 되고, Content-Type 헤더는 application/json 으로 설정하며, JSON.stringify()를 사용하여 데이터를 JSON으로 변환해서 JSON 형식으로 전송됩니다.