Question

I have a separate dbusername and dbpassword for each login user in a Play framework Scala application. Login credentials are first checked by against a stored Postgres database username and password. After a successful login it gets the user's dbusername and dbpassword, and connects to the database. How should I store the dbusername and dbpassword after login in the Play framework? Can I use global variables?

Was it helpful?

Solution

To clarify what you are doing here:

  1. You are using Postgres user credentials as your Play application user credentials.

  2. Database connections are authenticated with the user credentials, so you must be using database access control (i.e. GRANTs) for permissioning.

The first one is fine. The second is not, as it is not compatible with connection pooling. You would have to either: have a private connection pool per user (too many connections to your Postgres server), or open a new connection for every database access (slow). If your application will have more than a few users, I strongly recommend using the default database configuration in Play (single username/password in application.conf), which will use the built-in Play connection pool (i.e. the boneCP plugin). With this configuration, you would have a Postgres username/password for your Play application. You will have to implement permissioning in a different way.

To actually answer your question, here's the way to store information for a logged-in user:

  1. On successful login, store a session id in the Play session (not the user name, the session cookie is not encrypted).
  2. Store the user information in the cache, using the session id as part of the key. The cache is really a big global variable, so you were right about needing that!
  3. For each request, check if the session id is in the session. If not, the user is not logged in, so redirect to the login page. If the session id is valid but not in the cache, the session has expired, so redirect to login.

Update: if you have a small set of database credentials (corresponding to user roles), you can just use normal Play database configuration as follows:

1.In application.conf, create a set of db config settings, one for each role. For example:

db.guest.driver=org.postgres.???
db.guest.url=???
db.guest.user=theguest
db.guest.password=secret

2.At login, look up the user role, and store it in the cached session, as above. Then get the database connection using the connection name, like this:

val role = getRoleFromSession(request) // e.g. role = "guest"
play.api.db.DB.withConnection(role) { implicit c => ... }

OTHER TIPS

You should put the username/passwd into a configuration file, and use com.typesafe.config.ConfigFactory to load that info at runtime.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top