У меня есть два сервера с разными доменами.
Адрес сервера A
равен http://127.0.0.1:46833 (приложение dotnet core 2.1)
Адрес сервера B
на локальном IIS http://127.0.0.1:88.
Сервер A
предоставляет службу капчи, а сервер B
использует предоставленную службу капчи.
Вот так создается капча на сервере A
:
[ApiController]
public class CaptchaController : ControllerBase
{
[Route("get-captcha-image")]
public IActionResult GetCaptchaImage()
{
//it returns captcha image
var result = Captcha.GenerateCaptchaImage();
//store captcha
HttpContext.Session.SetString("CaptchaCode", result.CaptchaCode);
Stream s = new MemoryStream(result.CaptchaByteData);
return new FileStreamResult(s, "image/png");
}
}
А вот другие ключевые реализации на сервере A
:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor(); //inject httpContext
services.AddMemoryCache(); //enable cache
//cors
services.AddCors(options =>
{
options.AddPolicy("local",
builder => builder.WithOrigins("http://127.0.0.1:88").AllowAnyMethod().AllowAnyHeader().AllowCredentials());
});
// add session support
services.AddSession(options =>
{
options.IdleTimeout = TimeSpan.FromMinutes(20);
options.Cookie.HttpOnly = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
//cors
app.UseCors("local");
// add session support
app.UseSession();
}
}
Вот как сервер B
пытается использовать предоставленную капчу:
<form name="signup" action="" method="post">
<input name="CaptchaCode" type="text" />
<img src = "http://localhost:46833/api/captcha/get-captcha-image" />
<input id="btnSignUp" type="button" />
</form>
И, наконец, вот как сервер B
отправляет обратно вводимые на сервер контрольные данные A
:
$('#btnSignUp').click(function(){
$.ajax({
type: 'POST',
url: "http://localhost:46833/api/service/register",
data: JSON.stringify({
'CaptchaCode': $('input[name=CaptchaCode]').val()
}),
xhrFields: {
withCredentials: true
},
crossDomain: true,
dataType: "json",
contentType: "application/json"
});
});
К сожалению в методе register , значение HttpContext.Session.GetString("CaptchaCode")
является нулевым, и я не могу проверить это.Однако, когда я непосредственно тестирую сервер A
с почтальоном или другими браузерами, значение HttpContext.Session.GetString("CaptchaCode")
не равно нулю, и кажется, что сессия и капча работают нормально.
[HttpPost("Register")]
public async Task<IActionResult> RegisterAsync([FromBody] RegisterInputs inputs)
{
//here I check the value of HttpContext.Session.GetString("CaptchaCode")
if (!Captcha.ValidateCaptchaCode(inputs.CaptchaCode, HttpContext))
{
return StatusCode(401, new { message = "security code is not valid" });
}
}