2

我有一个应用程序,它本质上是一个位于 dotnet core 2.1 应用程序中的 Vue.JS SPA,提供 API 服务。当我使用当前的 Startup.cs 配置启动应用程序时,它会启动 3 个窗口。这些窗口中的 1 个是实际的 ASP.Net Core 应用程序根目录 - 其他 2 个(不要问我为什么 2 个)是您在执行时获得的 Vue.js 开发服务器的副本npm run serve

我遇到的问题是,虽然如果我使用在第一个窗口中运行的实例,身份验证工作正常,但如果我尝试使用 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);
    }

...和配置服务...

   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: [
    ]
}
4

1 回答 1

0

我最终通过配置应用程序解决了这个问题,以便它只在不处于开发模式时强制使用 HTTPS。HTTPS 正在杀死底层的 Webpack 开发服务器,因此热模块替换 - 我现在可以在主窗口中成功调试!

很高兴投票比这更好的解决方案,但要让它在不杀死 SSL 的情况下工作(如果可能的话)。

于 2019-05-31T19:02:56.743 回答