Search code examples
haskell-snap-framework

Authentication with Snap: Using a snaplet several times


I'm building a web application with Snap that needs to authenticate both staff and customers. So far I'm using the auth snaplet provided by snaplet-postgresql-simple to authenticate the two types of users from the same table in the database.

The initialization code therefore looks something like this:

s  <- nestSnaplet "sess" sess $ initCookieSessionManager sessionKeyfile "sess" Nothing (Just sessionTimeout)
db <- nestSnaplet "pg" pg Pg.pgsInit
a  <- nestSnaplet "auth" auth $ initPostgresAuth sess db

I'm considering separating the two types of users into two tables for these reasons:

  • the information associated with each type of user (i.e. the columns) is actually different (e.g. I don't need to know first and last names of staff)
  • I want to allow the staff to be authenticate to the backend without being logged into the frontend (I'd need separate cookies then, I guess)
  • I think security could benefit if the two types of users are in separate tables

I'm considering using two instances of the snaplets for postgresql-simple and sessions.

The initialization code would then look something like this:

s1  <- nestSnaplet "sess1" sess1 $ initCookieSessionManager sessionKeyfile "sess1" Nothing (Just sessionTimeout)
s2  <- nestSnaplet "sess2" sess2 $ initCookieSessionManager sessionKeyfile "sess2" Nothing (Just sessionTimeout)
db  <- nestSnaplet "pg" pg Pg.pgsInit
a1  <- nestSnaplet "auth1" auth1 $ initPostgresAuth sess1 db
a2  <- nestSnaplet "auth2" auth2 $ initPostgresAuth sess2 db

Is that possible to use several instances of a snaplet like that? Or does my problem have a better solution?


Solution

  • I wouldn't use two instances. I'd use a single instance where a user represents whatever is common to both, and then you add a user type column and put the extra information in other tables linked with a foreign key.