twitchax / AspNetCore.Proxy

ASP.NET Core Proxies made easy.
MIT License
524 stars 83 forks source link

[Question] Map all except controllers for SPA #99

Closed MeikelLP closed 2 years ago

MeikelLP commented 2 years ago

I previously tried to use Microsoft.AspNetCore.SpaServices.Extensions to develop a SPA (Vue) inside my aspnetcore app. Sadly this package does not support authentication thus everything send to my API controllers gets 304 redirected to my auth provider (Azure).

I thought maybe a "plain" proxy could do the same. That's how I landed here.

So far I got it working either way (but not both):

Any suggestions?

twitchax commented 2 years ago

There are multiple ways to do this. The easiest probably to use MapWhen, or to just be careful with the ordering.

You don't want RunProxy because RunProxy "stops" all other routing handlers registered with the middleware.

Can you share a snippet of your UseProxy code so I can help you with how to use it. Usually, the way it works is that each thing you call like Map or Use is put on a "stack" of middleware, so we can fit it together in a way where your controllers are matched "first", and everything else goes to the proxy.

However, I have a feeling that you may want something else entirely. Are you using a CDN, or are you proxying another server or microservice that you own? If it is "another server", then this is a good solution; if it is a CDN, then I would recommend a different approach, and I am happy to help you out. 😄

MeikelLP commented 2 years ago

Thanks for the quick response!

This is what my code looks like right now:

app.UseAuthentication();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
    // api controllers
    endpoints.MapControllerRoute(
        name: "areas",
        pattern: "{area}/{controller}/{action=Index}/{id?}");
});
if (env.IsDevelopment())
{
    app.UseProxies(builder =>
    {
        builder.Map("/", x =>
        {
            x.UseHttp("http://localhost:5173");
        });
    });
}
else
{
    app.UseStaticFiles();
}

I do not want to forward my requests to a CDN. I have a local Vue dev server (vite.js) and aspnetcore should redirect every request except controller routes to that server.

MeikelLP commented 2 years ago

I was able to make it work with this mapping:

proxies.Map("{*url}", proxy =>
{
    proxy.UseHttp((_, args) => $"http://localhost:5173/{args["url"]}");
});

Is this a good approach?

twitchax commented 2 years ago

Yes, that should work, but I think you want to use ** for nested folders, etc. Using just * will escape things like slashes, so my/path would become my%2Fpath. If you use **, then my/path stays as my/path.

MeikelLP commented 2 years ago

That's interesting because it works for subfolders as well. From what I understand from the docs is that * is equal to **. So it's just a matter of preference?

twitchax commented 2 years ago

Cool: that's fine then. :)