I am trying to use the Dropbox.Api dotnet SDK, which is built on netstandard 2.0, by translating the example from the docs here into a Blazor Webassembly project. I have narrowed down the issue to the fact that the PKCEOAuthFlow
class uses private members CodeVerifier
and CodeChallenge
to implement the PKCE flow, and these private members are generated and set only in the constructor, which makes sense.
So here is specifically where I am stuck: How can I persist that exact object with its one-time generated CodeVerifier/CodeChallenge
which must be the same when I try to call ProcessCodeFlowAsync
after the Dropbox redirect back to my app?
I have tried the following:
- Opening the dropbox authorize URL in a new tab so that the main tab stays open. This fails because when Dropbox redirects the user back, they stay in the new tab and my object is only still alive back in the first tab.
- Making an
ILoginService
class, injecting it into my pages as a singleton by doingbuilder.Services.AddSingleton<ILoginService, DropboxLoginService>();
insideProgram.cs
, but I always get a new one. I am not sure exactly why this fails, but I believe that the entire Webassembly app goes out of scope when I send the user to Dropbox and after the redirect it has to create a newILoginService
anyways. - I also tried making my entire
DropboxLoginService
classstatic
, with a staticPKCEOAuthFlow
member set in the static constructor. I also end up with a new object every time when I do it this way, probably for the same reason as #2. - I tried saving my object to the browser session storage using
Blazored.SessionStorage
, but I quickly realized this does not persist any private members, and the object that I retrieve after the redirect again has a newCodeVerifier
andCodeChallenge
. - DID NOT TRY THIS YET - I think that MAYBE I could serialize the entire object in some binary format, then save a base64 string to the session storage to retrieve it later. However, this feels like a security hole considering that the whole point of PKCE is to avoid untrustworthy storage with sensitive information. It would basically negate the security since an intrepid hacker could possibly get at that object and MITM my user somehow. Basically it is no more secure than going back to normal OAuth2 with my app secret stored somewhere.
Am I making this too complicated? Is there some way to keep my PKCEOAuthFlow
object in memory from the start to the end of my flow, across the 2 redirects from my app -> Dropbox -> back to my app? I think this question goes beyond Dropbox and would apply to any OAuth2 + PKCE flow implementation in Blazor Webassembly, or really any serverless SPA or PWA.