fsbolero / Bolero

Bolero brings Blazor to F# developers with an easy to use Model-View-Update architecture, HTML combinators, hot reloaded templates, type-safe endpoints, advanced routing and remoting capabilities, and more.
https://fsbolero.io
Apache License 2.0
1.06k stars 53 forks source link

Blazor interactive render modes compatibility #347

Open Tarmil opened 9 months ago

Tarmil commented 9 months ago

Based on my experimentations, Bolero is mostly compatible with the new .NET 8 Blazor interactive modes (aka Blazor United, ie InteractiveServer, InteractiveClient and InteractiveAuto render modes). See https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0

There is a caveat that Bolero's routing is not compatible with having different render modes for different pages; you need to specify a mode on the ProgramComponent. Using different render modes for different pages only works with Blazor's built-in, attribute-based routing.

We need some improvements to integrate it better:

fwaris commented 8 months ago

@Tarmil the interactive login using MSAL.js (and blazor wrapper) started failing when I moved my .Net 7 app to .Net 8.

The authentication uses Bolero page routing to redirect:

match model.page with 
| Page.Authentication action -> 
    ecomp<LoginRedirectView,_,_> (action,model) dispatch {attr.empty()}
| Page.Home -> 
    ...

Where ecomp uses the RemoteAuthenticatorView (from "Microsoft.Authentication.WebAssembly.Msal" package that handles the actual callback.

So far, I have not been able to fix this issue. I am wondering if it could be related to what you have described here related to render modes?

Tarmil commented 8 months ago

@fwaris I wouldn't expect existing code to break due to this; interactive render modes are a new alternate way of managing rendering, but existing ones are still valid.

As a sanity check, did you also upgrade Microsoft.Authentication.WebAssembly.Msal (and even all your Microsoft.* dependencies) to v8.0.0? I wouldn't be surprised if that is necessary.

fwaris commented 8 months ago

@Tarmil, after some investigation I discovered a few things.

The MSAL authentication fails only when the app is deployed to Azure app service (only this mode tested) - AND prerendered=true.

(Locally, all is fine (debug/release ; .Net 7/8; prerendered=true/false)

The Azure app starts to work fine if I set prerendered=false.

The F#/Bolero app has both client and server sides. I modeled the authentication configuration after the C# example below.

The C# example works fine when deployed to Azure. I created it from this MS article, as follows:

dotnet new blazorwasm -au SingleOrg --client-id "{CLIENT ID}" -o {PROJECT NAME} --tenant-id "{TENANT ID}"

(The repo is here: https://github.com/fwaris/BlzHstdAuth)

I am not sure if in C# RemoteAuthenticatorView is actually being rendered just on the client (and so is equivalent to prerendered=false in F#).

The C# has both client-side and server-side authentication configurations (in respective appSettings.json files). Both are being used somehow.

With prerendered=true (and deployed to Azure) causes some type of javascript error on the msal.js UI. This happens right at the end when the callback with token has been received.

Tarmil commented 8 months ago

@fwaris Yes, the C# version uses an index.html which means it doesn't have prerendering. So I guess if disabling prerendering is acceptable for you then that's the solution.

fwaris commented 8 months ago

got it. thanks. yes not having prerendering is fine in my case