首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取API - Cant从ASP标识API获取登录cookie

获取API - Cant从ASP标识API获取登录cookie
EN

Stack Overflow用户
提问于 2021-05-08 19:23:45
回答 2查看 595关注 0票数 0

我试图在一个成功的登录后得到饼干,但我不知道如何。在ASP.NETCoreIdentity API上,浏览器使用swagger获得cookie,但当我使用fetch api时,无法获得cookie。我尝试返回返回的response.json();但是这不起作用。在登录成功时,我还可以重定向到主页,但我不确定如何返回response.json();如果需要的话。

标识api和localhost都在本地主机上运行。

JS -获取API - POST:

代码语言:javascript
复制
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。

代码语言:javascript
复制
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:中的登录方法

代码语言:javascript
复制
 // 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,如下所示:

代码语言:javascript
复制
services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder =>
                builder.SetIsOriginAllowed(_ => true)
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials());
        });

和Js邮政代码:

代码语言:javascript
复制
 // 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。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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头中使用,因此您必须明确说明您希望允许的源--即客户端应用程序的起源,将源定义为协议、域和端口的组合。

票数 1
EN

Stack Overflow用户

发布于 2021-05-09 10:54:42

现在工作了,多亏了@IAmDranged

JS -获取Api - Post方法:

代码语言:javascript
复制
 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:

代码语言:javascript
复制
 // 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  
.................................................

因此,的修正是:

  1. 添加到JS - fetch方法:

模式:“cors”,凭据:“包含”

  1. 添加到Asp net startup.cs

app.UseCors(x => x)

代码语言:javascript
复制
                    .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部分--它允许所有。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67451351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档