Pow: Multiple User Contexts/Schemas

Created on 8 Sep 2018  路  6Comments  路  Source: danschultzer/pow

In my app, I have the need for multiple user tables.

Devise does a killer job (via warden) to authenticate via varying tables & warden scopes.

Is there a good mechanism to do this with this library (without an umbrella)?

Most helpful comment

This is a great use case for Pow 馃槃 I'll test it out to see what tweaks are necessary, but I think that it's almost doable. The user sessions themselves are isolated.

But if Pow.Plug.Session is called multiple times in the same scope, it'll only fetch the last plug configuration in the controllers. It should be possible to fix if I can pass namespace configuration to routes.

I'll get back to this later when I've got a chance to work on it.

All 6 comments

Yeah, Pow is built to be very flexible in this regard. The configuration happens in the plug:

plug Pow.Plug.Session,
  repo: MyApp.Repo,
  user: MyApp.User,
  current_user_assigns_key: :current_user,
  session_key: "auth",
  session_store: {Pow.Store.CredentialsCache,
                  ttl: :timer.minutes(30),
                  namespace: "credentials"},
  session_ttl_renewal: :timer.minutes(15),
  cache_store_backend: Pow.Store.Backend.EtsCache,
  users_context: Pow.Ecto.Users

So you should be able to set it up with scopes.

I would love to see a tutorial or demo for how it works in Devise so I can confirm that Pow can do the same thing. Is this what you want? https://github.com/plataformatec/devise/wiki/How-to-Setup-Multiple-Devise-User-Models

That's basically it (for devise).
For my needs devise is perfect b/c I don't deal with scoping/authorization. I can use the devise scope current_admin, current_buyer, current_seller respectively, and it pretty well isolates the concerns of those users. 馃槂

This is a great use case for Pow 馃槃 I'll test it out to see what tweaks are necessary, but I think that it's almost doable. The user sessions themselves are isolated.

But if Pow.Plug.Session is called multiple times in the same scope, it'll only fetch the last plug configuration in the controllers. It should be possible to fix if I can pass namespace configuration to routes.

I'll get back to this later when I've got a chance to work on it.

I'm working on a PR to make this possible right now. It will work like this:


Set up Pow to handle multiple user structs in same scope

Let's say that you would like to access both a user and admin session in the same scope.

Pow has built-in isolation with :namespace configuration, so this will be simple. Note that the same can be done with less configuration in an umbrella setup using the :otp_app configuration.

Create admin and user schema

mix pow.ecto.install -r MyApp.Repo Admin admins
mix pow.ecto.install -r MyApp.Repo User users

Set up plugs

Update WEB_PATH/endpoint.ex with the two namespaced configurations:

plug Pow.Plug.Session,
  repo: MyApp.Repo,
  user: MyApp.User,
  namespace: :user

plug Pow.Plug.Session,
  repo: MyApp.Repo,
  user: MyApp.Admin,
  namespace: :admin

The user can be accessed in assigns[:current_user][:user] and assigns[:current_user][:admin], and the configurations can be accessed in conn.private[:pow_config][:user] and conn.private[:pow_config][:admin].

Set up routes

Update WEB_PATH/router.ex to access the namespaced configurations:

scope "/user", private: %{pow_config_namespace: :user} do
  pipe_through :browser

  pow_routes()
end

scope "/admin", private: %{pow_config_namespace: :admin} do
  pipe_through :browser

  pow_routes()
end

That's it! Your namespaced configuration is now shared with the controller.

Modify templates

If you wish to modify the templates, you'll need to generate run the generate mix task with namespace argument:

mix pow.phoenix.gen.templates --namespace user
mix pow.phoenix.gen.templates --namespace admin

Remember to set up both configurations with web_module: MyAppWeb. The namespace is automatically used from the configuration to discover the templates and views.

Sorry for the delay, other work took my time. I've created a PR #24.

You can read the guide here: https://github.com/danschultzer/pow/blob/e725d04b2a9e91565a1c7c1075411e0ae2cec792/guides/MULTIPLE_USERS_IN_SAME_SCOPE.md

I've closed #24 as I didn't feel it was the right approach. I think this is better left to the developer as there's several things to consider in how the contexts are separated. Pow has been refactored quite a lot and with #56, it's now possible to handle several contexts with routes too. This was the last issue that bugged me. Most of the work will just be in figuring out how the pipelines in the router should be set up.

I'll prepare for a 1.0.0 release first, but eventually I'll look into a guide explaining how to handle multiple contexts in same connection with Pow 馃槃

Was this page helpful?
0 / 5 - 0 ratings

Related issues

th31nitiate picture th31nitiate  路  5Comments

danschultzer picture danschultzer  路  3Comments

danschultzer picture danschultzer  路  6Comments

dweremeichik picture dweremeichik  路  7Comments

blatyo picture blatyo  路  4Comments