I’m working on implementing authentication in a Halogen app and I’m trying to find a neat way to require authentication in a component.
A common pattern seems to be to use something like guardSession
from the real world halogen project, which looks like this:
-- | Several components verify that a current user exists and, if there is none in state, log the
-- | user out and redirect to the home page. This way, an inadvertent route to the settings page,
-- | for example, is protected at initialization.
guardSession
:: forall m r
. MonadEffect m
=> MonadAsk { currentUser :: Ref (Maybe Profile) | r } m
=> Navigate m
=> m (Maybe Profile)
guardSession = do
asks _.currentUser >>= (Ref.read >>> liftEffect) >>= case _ of
Nothing -> logout *> pure Nothing
Just profile -> pure (Just profile)
This would be used something like this:
eval = case _ of
Initialize a -> do
void $ H.fork $ eval $ LoadTags a
guardSession >>= case _ of
Nothing -> do
void $ H.fork $ eval $ LoadArticles noArticleParams a
profile -> do
void $ H.fork $ eval $ LoadFeed { limit: Just 20, offset: Nothing } a
H.modify_ _ { currentUser = profile, tab = Feed }
pure a
This works well enough but I feel like there’s a different way I would like to express things. I would like to require that the application give me an auth token. Something like this:
eval = case _ of
Initialize a -> do
token <- fetchAuthToken
... -- do things with auth token
What I would want to happen here is that the application would suspend execution at this point, show a login form, perform authentication, then return to the same point with the value of the token.
That feels a lot like a coroutine, so it feels like I should be looking at writing a natural transformation from my application query language (which is built using purescript-run
, although I’m not wedded to the extensible effects style) to Aff
that uses coroutines. But I can’t work out what that might look like.
Has anyone any experience with doing something like this? Any tips? I appreciate that it’s not a particularly well defined question.