haskell-webapps icon indicating copy to clipboard operation
haskell-webapps copied to clipboard

Discussing the authentication spec

Open saurabhnanda opened this issue 9 years ago • 1 comments

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/new and if the remember_me flag is set, the backend sends back an encrypted persistent cookie, called auth_token
  • This auth_token is set to never expire, BUT does not control the current session.
  • The auth_token needs to be periodically exchanged for a session_id every X minutus, where X=the session timeout time.
  • The UI will need to detect when the backend sends a session expired response and make an API call to /session/refresh automatically.
  • After decrypting the session_id the 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 the session_id was 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?

saurabhnanda avatar Oct 11 '16 06:10 saurabhnanda

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

wz1000 avatar Oct 15 '16 10:10 wz1000