Discussing the authentication spec
Before we start implementing the endpoints described in the authentication section, I feel we need to have a discussion about the endpoints themselves. The thought behind designing the endpoints in this way was:
- User does a sign-in via
/sessions/newand if theremember_meflag is set, the backend sends back an encrypted persistent cookie, calledauth_token - This
auth_tokenis set to never expire, BUT does not control the current session. - The
auth_tokenneeds to be periodically exchanged for asession_idevery X minutus, where X=the session timeout time. - The UI will need to detect when the backend sends a
session expiredresponse and make an API call to/session/refreshautomatically. - After decrypting the
session_idthe backend should always check a server-side data store (could be the DB, or could be Redis) to ensure that the session is still alive. Just because thesession_idwas successfully decrypted, should not mean that the session is valid. Checking a server-side data-store allows the server to invalidate existing user sessions (eg. if one has to implement a "logout all other sessions" feature)
The obvious downside of this is the additional complexity. The upside is that something like this allows us to implement a "sudo mode", like Github.
Thoughts?
This wouldn't be too difficult to achieve. I achieve session validation by this code
cookieAuthHandler :: AuthCookieSettings -> ServerKey -> AuthHandler Request (Either CookieError Session)
cookieAuthHandler authSettings serverKey = mkAuthHandler $ \request -> do
result <- try $ getSession authSettings serverKey request
case result :: Either AuthCookieException (Maybe Session) of
Left a -> return $ Left $ AuthError a
Right a -> return $ maybe (Left NotPresent) Right a
The cookie is decrypted(which can fail with an AuthCookieException) to a Maybe Session(which would be nothing if the cookie does not exist). Then we verify whether it exists and throw a (NotPresent :: CookieError) otherwise.
Any kind of further validation logic can simply be added to this function, which can fail with the appropriate CookieError