我对用于身份验证的会话/cookie 很陌生,所以我正在慢慢了解一切。
我有一个 Web API,它有一些用于登录的端点,还有一个受保护的端点,只有在 cookie 发出且未过期后才能访问该端点。
只是为了测试如何在前端处理它,我创建了一个调用这些端点的简单表单。
登录端点工作正常,我确实获得了在后端配置的 cookie,但对于其他受保护端点,我收到 302 Found 错误(我有一个按钮在登录后调用此受保护端点),即使这在我使用邮递员时有效。即,我可以访问受保护的端点。这会将我重定向到我尚未设置的另一个端点(我猜它是 .NET 设置的端点?)
登录端点:
登录后直接调用授权端点:
另一件事是,后端问题的这个 cookie 在我的页面重新加载/刷新后被删除,我不知道为什么。
我也希望获得有关如何安全有效地处理前端和后端会话身份验证的任何指导。
这是我的代码:
身份验证配置 - 我将其设置为较低的过期时间以进行测试
public static IServiceCollection AddApplicationCookieAuth(this IServiceCollection services)
{
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
}).AddCookie(options => {
options.Cookie = new() {
Name = "MySessionAuthCookie",
HttpOnly = true
};
options.ExpireTimeSpan = TimeSpan.FromSeconds(30);
options.SlidingExpiration = true;
});
return services;
}
控制器端点:
// Protected endpoint
[HttpGet]
[Authorize]
public IActionResult GetProtectedData()
{
return Ok("Protected data");
}
[HttpPost("login")]
public async Task<IActionResult> Login(LoginRequest request)
{
var user = await _userManager.FindByNameAsync(request.Email);
if (user != null && await _userManager.CheckPasswordAsync(user, request.Password))
{
var claims = new List<Claim>
{
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Role, "Admin")
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var authProperties = new AuthenticationProperties { IsPersistent = true };
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(claimsIdentity), authProperties);
return Ok("Login success");
}
return Unauthorized();
}
我的前端只是用于演示目的的常规 HTML 和 JS。
async function protectedEndpoint() {
try {
const res = await axios.get("https://localhost:7009/api/auth", {withCredentials: true, });
console.log('Response:', res);
} catch(err) {
console.error('Error:', err);
}
}
async function authenticate(data) {
try {
const res = await axios.post("https://localhost:7009/api/auth/login", data, {withCredentials: true});
console.log('Response:', res);
} catch(err) {
console.error('Error:', err);
}
}
尝试使用 CookiePolicyOptions 与类似的东西
services.Configure<CookiePolicyOptions>(options =>
{
options.ConsentCookie.IsEssential = true;
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
并阅读 microsoft learn 页面,特别是安全和身份部分,在这里您可以学习多种身份验证类型 Microsoft Learn