Hello Luke.
I made an api servant with authorization. I think you may have solved your problem by now, but I'll post it here for other people.
I started from the same base as your second example of how to make a servant api as a subsite in yesod
I have an EmbeddedAPI:
newtype EmbeddedAPI = EmbeddedAPI { eapiApplication :: Application }
instance RenderRoute EmbeddedAPI where
data Route EmbeddedAPI = EmbeddedAPIR ([Text], [(Text, Text)]) deriving(Eq, Show, Read)
renderRoute (EmbeddedAPIR t) = t
instance ParseRoute EmbeddedAPI where
parseRoute t = Just (EmbeddedAPIR t)
instance Yesod master => YesodSubDispatch EmbeddedAPI master where
yesodSubDispatch YesodSubRunnerEnv{..} req = resp
where
master = yreSite ysreParentEnv
site = ysreGetSub master
resp = eapiApplication site req
In the blog below, the author makes a subsite, but uses the WaiSubsite function. I simply adapted to use WaiSubsiteWithAuth.
My route looked like this:
-- By default this file is used by `parseRoutesFile` in Foundation.hs
-- Syntax for this file here: https://www.yesodweb.com/book/routing-and-handlers
-- API REST routes
/api/v1/products-manager SubsiteR EmbeddedAPI appAPI
/static StaticR Static appStatic
/auth AuthR Auth getAuth
/api/v1 HomeR GET
/api/v1/login UsersLoginR POST
I changed it to be like the blog, but putting WaiSubsiteWithAuth in place:
-- By default this file is used by `parseRoutesFile` in Foundation.hs
-- Syntax for this file here: https://www.yesodweb.com/book/routing-and-handlers
-- API REST routes
/api/v1/products-manager SubsiteR WaiSubsiteWithAuth getServantWithAuth
/static StaticR Static appStatic
/auth AuthR Auth getAuth
/api/v1 HomeR GET
/api/v1/login UsersLoginR POST
The '/api/v1/login' route is not subsite and I use it to authenticate.
In foundation I put the function getServantWithAuth as below:
getServantWithAuth :: App -> WaiSubsiteWithAuth
getServantWithAuth = WaiSubsiteWithAuth . eapiApplication . appAPI
eapiApplication is the Application field in EmbeddedAPI.
As a bonus, you can also see the example of this code that shows how to use JWT authentication:
I just didn't understand why he used the word 'token' when he took the token in the http header, in this excerpt:
extractToken :: Text -> Maybe Text
extractToken auth
| toLower x == "token" = Just $ dropWhile isSpace y
| otherwise = Nothing
where (x, y) = break isSpace auth
The header schema is when using JWT for example: "Bearer kgTvnjciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqd3QiOjF9.8oq_FD7t71bbdsf-DsVwpugtdfJUhTgba4W_GEdknSc".
So change like this:
extractToken :: Text -> Maybe Text
extractToken auth
| toLower x == "bearer" = Just $ dropWhile isSpace y
| otherwise = Nothing
where (x, y) = break isSpace auth
It all works.
Em domingo, 23 de agosto de 2020 19:18:58 UTC-3, Rodolpho Pueyrredón escreveu: