我试图在一个成功的登录后得到饼干,但我不知道如何。在ASP.NETCoreIdentity API上,浏览器使用swagger获得cookie,但当我使用fetch api时,无法获得cookie。我尝试返回返回的response.json();但是这不起作用。在登录成功时,我还可以重定向到主页,但我不确定如何返回response.json();如果需要的话。
标识api和localhost都在本地主机上运行。
JS -获取API - POST:
function IdentityPost(formID, postUrl) {
const currForm = document.getElementById(formID); // Get the Form
var submitBtn = currForm.elements.namedItem("triggerSubmit"); // Get the submit button of the form
// Listen for Form- Submit
currForm.addEventListener('submit',function handler(e)
{
e.preventDefault(); // Prevent page reload on Submit
submitBtn.disabled = true; // Disable the submit button
LoadingMsg(); // Show Loading Message
// Get form data as string---------------------------------------------------------------
const formData = new FormData(this); // "this" = this Form
const searchParams = new URLSearchParams(formData); // Get the form data params
let formQueryString = searchParams.toString(); // Get the form data params as string
// POST ----------------------------------------------------------------------------------
fetch(identityApiUri + postUrl + formQueryString, // #1 = API-Address, #2 = API - Controller/Mehod, #3 = form data as sring
{
method: 'POST',
credentials: 'same-origin'
}).then(function (response)
{
// IF OK
if (response.status == 200 || response.status == 201) // Status 201 = "Created"
{
RemoveLoadingMsg();
SuccessMsg("Success");
currForm.reset(); // Reset the form
submitBtn.disabled = false; // Enable Submit button
if (document.referrer.split('/')[2] === window.location.host) // Return to previous page if local
{
history.back(); // Go back to previouse page
}
else
{
window.location.href = "/"; // RETURN TO Home
}
}
else // If Bad STATUS
{
return Promise.reject(response); // Triggers Catch method
}
}).catch(function (err) // If Exception
{
RemoveLoadingMsg();
// Show Error
try // Because of JSON Parse and err.text()
{
err.text().then(errorMessage => {
var error = errorMessage.substring(1, errorMessage.length - 1); // Remove the [..] form the Msg
ErrorMsg(error); // Get the error and display
});
}
catch(e)
{
console.warn("Post Exception - Probably No connection to hte server");
ErrorMsg(err + " - Server is probably offline"); // Get the error and display
}
submitBtn.disabled = false; // Enable Submit button
console.warn('Post Exception:', err);
});
this.removeEventListener('submit', handler); // Remove Event Listener
});
}ASP.NET核心-标识API -启动:我已启用CORS任何来源.-不确定是否需要ti包括.AllowCredentials()。如果我试图启用它,它会说我不能启用.AllowAnyOrigin()。我直接从客户端“浏览器”访问Api。
using Leanheat.Identity.API.DBContexts;
using Leanheat.Identity.API.Filters;
using Leanheat.Identity.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Leanheat.Identity.API
{
public class Startup
{
// Startup
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// Configure Services =================================================================================
public void ConfigureServices(IServiceCollection services)// This method gets called by the runtime. Use this method to add services to the container.
{
// Log in - DbContext
services.AddDbContextPool<LeanheatIdentityApiContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("IdentityContextConnection")));
// UnitOfWork - Filter
services.AddScoped<UnitOfWorkFilter>();
services.AddControllers(config => { config.Filters.AddService<UnitOfWorkFilter>(); }); // UnitOfWork for all Controllers
// CORS - Allow calling the API from WebBrowsers
services.AddCors();
// Log In
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
// Password settings
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
}).AddEntityFrameworkStores<LeanheatIdentityApiContext>().AddDefaultTokenProviders(); // AddDefaultTokenProviders is used for the Update Log In Password etc.
// Log In
// Make all Controllers protected by default so only Authorized Users can accsess them, for Anonymouse Users use [AlloAnonymouse] over the controllers.
services.AddMvc(options => {
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddXmlSerializerFormatters();
//services.AddControllers();
// Swagger
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Leanheat.Identity.API", Version = "v1" });
});
}
// Configure ===========================================================================================
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
{
// Default Code------------------------------------------------------------------------------------>
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// Swagger
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Leanheat.Identity.API v1"));
}
app.UseHsts(); // Allow HTTPS
app.UseHttpsRedirection();
app.UseRouting();
// CORS - Allow calling the API from WebBrowsers
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin()
.SetIsOriginAllowed(origin => true));// allow any origin
// Log In
app.UseAuthentication(); // UseAuthentication SHOULD ALWAYS BE BEFORE Authorization
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}标识API:中的登录方法
// Log In ===================================================================================
[HttpPost]
[Route("LogIn")]
[AllowAnonymous]
public async Task<IActionResult> LogIn(string email, string password, bool rememberMe)
{
if(email != null && password !=null)
{
var result = await signInManager.PasswordSignInAsync(email, password, rememberMe, false);
if (result.Succeeded) // If Login Ok
{
return new JsonResult(result);
}
return StatusCode(401, "[\n \"Invalid Log In\" \n]"); // If Erors return errors
}
return StatusCode(401, "[\n \"Email or Password cant be empty\" \n]");
}使用swagger我可以在浏览器中获得cookie:

编辑-几乎可以工作:i在startup.cs中添加了标识API,如下所示:
services.AddCors(options =>
{
options.AddDefaultPolicy(builder =>
builder.SetIsOriginAllowed(_ => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});和Js邮政代码:
// POST ----------------------------------------------------------------------------------
fetch(identityApiUri + postUrl + formQueryString, // #1 = API-Address, #2 = API - Controller/Mehod, #3 = form data as sring
{
method: 'POST',
mode: 'no-cors',
headers: {
'Access-Control-Allow-Origin': '*'
},
credentials: 'include',现在我得到了cookie,但我也得到了异常:服务器正在返回Statuscode 200,我现在可以获得cookie,但是在fetch api方法中得到异常。

Ok: false --但是我得到了cookie,服务器返回状态200。

发布于 2021-05-08 21:00:34
您是从与api不同的来源调用fetch()的,对吗?如果是这样的话,这听起来像是一个简单的CORS问题。
默认情况下,CORS不包括cookies之类的凭据。您必须选择在客户端设置凭据模式,在服务器端设置Access-Control-Allow-Credentials头。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials
使用fetch() api,使用credentials: 'include'选项设置凭据模式。至于服务器端,我不熟悉ASP,但它似乎提供了一些方便的方法来设置相关的头。
正如您在文章中所暗示的那样,当Access-Control-Allow-Credentials头被设置为true时,*值--意思是任何源--实际上不能在Access-Control-Allow-Origin头中使用,因此您必须明确说明您希望允许的源--即客户端应用程序的起源,将源定义为协议、域和端口的组合。
发布于 2021-05-09 10:54:42
现在工作了,多亏了@IAmDranged

JS -获取Api - Post方法:
fetch(identityApiUri + postUrl + formQueryString, // #1 = API-Address, #2 = API - Controller/Mehod, #3 = form data as sring
{
method: 'POST',
mode: 'cors',
//headers: {
// 'Access-Control-Allow-Origin': 'https://localhost',
//},
credentials: 'include'
}).then(function (response)
{ ...........................Asp网络核心标识API - Startup.cs:
// Configure ===========================================================================================
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
// CORS
app.UseCors(x => x
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("https://localhost:44351")); // Allow only this origin
//.SetIsOriginAllowed(origin => true));// Allow any origin
.................................................因此,的修正是:
模式:“cors”,凭据:“包含”
app.UseCors(x => x)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("https://localhost:44351")); // Allow only this origin
//.SetIsOriginAllowed(origin => true));// Allow any origin .WithOrigins("https://localhost:44351"));只允许客户端使用api,如果我使用.SetIsOriginAllowed(origin => true));而不使用WithOrigins部分--它允许所有。
https://stackoverflow.com/questions/67451351
复制相似问题