簡體   English   中英

ASP.Net Core 2.1 Vue.JS SPA - Cookie Auth和Vue.JS Dev Server

[英]ASP.Net Core 2.1 Vue.JS SPA - Cookie Auth and the Vue.JS Dev Server

我有一個應用程序,它本質上是一個位於dotnet核心2.1應用程序中的Vue.JS SPA,提供API服務。 當我啟動應用程序時,使用我當前的Startup.cs配置,它啟動3個窗口。 其中1個窗口是實際的ASP.Net Core應用程序根目錄 - 另外2個(不要問我為什么2)是你在執行npm run serve時獲得的Vue.js開發服務器的副本。

我遇到的問題是,如果我使用在第一個窗口中運行的實例,身份驗證工作正常,如果我嘗試使用Vue.JS服務器窗口登錄,那么我只需要返回401。

我的第一個想法是CORS,所以我設置了一個純粹用於在開發模式下運行的CORS策略,但這並沒有糾正這個問題。 沒有Vue.JS服務器的開發實際上並不可行,因為沒有它我沒有HMR,並且每次我進行設計更改時都需要重新加載整個應用程序狀態。

我之前使用.net Framework 4.6 API后端設置工作沒有任何問題所以我只能認為這是一個現代的安全增強功能,它阻止了我需要配置為在開發中關閉的代理。

有關如何解決這個問題的任何建議都是受歡迎的。

這是我目前的Startup.cs配置...

       public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory,
        ApplicationDbContext context, RoleManager<IdentityRole> roleManager, UserManager<ApplicationUser> userManager)
    {
        if (env.IsDevelopment())
        {
            app
                .UseDeveloperExceptionPage()
                .UseDatabaseErrorPage()
                .UseCors("DevelopmentPolicy");
        }
        else
        {
            app
                .UseExceptionHandler("/Home/Error")
                .UseHsts();
        }

        app
            .UseAuthentication()
            .UseHttpsRedirection()
            .UseStaticFiles()
            .UseSpaStaticFiles();

        app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });

        app.UseSpa(spa =>
        {
            spa.Options.SourcePath = "VueApp";

            if (env.IsDevelopment())
            {
                spa.UseVueCliServer("serve");
            }
        });

        DbInitializer.Initialize(context, roleManager, userManager, env, loggerFactory);
    }

...和ConfigureServices ...

   public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddLogging(builder => builder
                .AddConsole()
                .AddDebug());

        services
            .AddMvc()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
                .AddJsonOptions(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver());

        services
            .AddCors(options =>
            {
                options.AddPolicy("DevelopmentPolicy",
                    policy => policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
            });

        // In production, the Vue files will be served from this directory
        services.AddSpaStaticFiles(configuration => { configuration.RootPath = "wwwroot"; });
        services.AddAuthentication();

        services
            .ConfigureEntityFramework(Configuration)
            .ConfigureEntityServices()
            .ConfigureIdentityDependencies()
            .ConfigureDomainServices()
            .ConfigureApplicationCookie(config =>
            {
                config.SlidingExpiration = true;
                config.Events = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = cxt =>
                    {
                        cxt.Response.StatusCode = 401;
                        return Task.CompletedTask;
                    },
                    OnRedirectToAccessDenied = cxt =>
                    {
                        cxt.Response.StatusCode = 403;
                        return Task.CompletedTask;
                    },
                    OnRedirectToLogout = cxt => Task.CompletedTask
                };
            });
    }

...和身份在這里與EF配置混在一起......

       public static IServiceCollection ConfigureEntityFramework(this IServiceCollection services, string connectionString)
    {
        services
            .AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString))
            .AddIdentity<ApplicationUser, IdentityRole>(options =>
                {

                    // Password settings
                    options.Password.RequireDigit = true;
                    options.Password.RequiredLength = 8;
                    options.Password.RequireNonAlphanumeric = true;

                    // Lockout settings
                    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
                    options.Lockout.MaxFailedAccessAttempts = 10;

                    // User settings
                    options.User.RequireUniqueEmail = true;
                })
            .AddRoleManager<RoleManager<IdentityRole>>()
            .AddSignInManager<SignInManager<ApplicationUser>>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        return services;
    }

我的vue.config.js看起來像這樣......

const baseUrl = ''

module.exports = {
    publicPath: baseUrl + '/',

    // place our built files into the parent project where they will be copied
    // into the distribution for deployment
    outputDir: '../wwwroot',

    filenameHashing: true, //process.env.NODE_ENV === 'production',
    lintOnSave: 'error',

    css: {
        modules: false,
        sourceMap: process.env.NODE_ENV !== 'production',
        loaderOptions: {
            sass: {
                data: `
                    $fa-font-path: ${process.env.NODE_ENV !== 'production' ? '"~/fonts"' : '"' + baseUrl + '/fonts"'};
                    @import "@/scss/base/index.scss";
                    @import "@/scss/helpers/index.scss";
                `
            }
        }
    },

    devServer: {
        host: 'localhost',
        port: 8080,
        hot: true,
        open: true,
        openPage: '',
        overlay: true,
        disableHostCheck: true,
        proxy: {
            // Proxy services to a backend API
            '/api': {
                target: process.env.PROXY || 'https://localhost:44368',
                secure: false,
                changeOrigin: true
            }
        }
    },

    // these node_modules use es6 so need transpiling for IE
    transpileDependencies: [
    ]
}

我最后通過配置應用程序解決了這個問題,因此它只在不處於開發模式時強制使用HTTPS。 HTTPS正在殺死底層Webpack Development Server,因此更換熱模塊 - 我現在可以在主窗口中成功調試!

很高興投票比這更好的解決方案,但要讓它工作而不殺死SSL(如果可能的話)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM