I was curious if there was a way to configure the user module that the context references more dynamically based on which application hits the application hits the context module?
It’s possible if you are able to tell what struct to use based on the params, but you’ll have to override all the methods. Also in this case you should just use the @behaviour instead of the macro.
Feel free to open an issue on github to share your setup, there may be alternatives depending on your exact use case.
Thank you so much! It is easy and explicit for us to pull out a separate context for this separate set of users so no problem, was just curious. Thanks Dan!
For the last year I’ve been working full time on open source using my own funds. It’s been a great experience, so now I’m experimenting with GitHub Sponsors to see how this could work longer term. If you use Pow for your business and would like to show support, here’s the link: https://github.com/sponsors/danschultzer
These were two meaty releases that mostly has a lot of under-the-hood improvements.
Prevent user enumeration
Pow now protects against user enumeration attacks when PowEmailConfirmation extension is enabled. As an example, this means that instead of an error message being shown if an e-mail is already taken, the user will see a message that informs them to check their inbox to confirm the e-mail the same way as if the registration succeeded.
Thanks for developing Pow and Pow Ascent, it’s great to have such a good framework for authentication in Elixir.
I had a question on unlinking from auth provider like Google, what is the expected result? It redirects to the change password page, I was expecting it to leave the user record and ask to set a password, but maybe I misunderstood the flow.
I’m trying to integrate Pow with an API following the API guide docs. I was wondering if there’s a way to stop Pow.Plug.create_user ( which is used from a RegistrationController ) from creating a new session if the user creation is successful. I want to just send a confirmation email and redirect to my login page client-side instead.
I can’t find any callback within Pow.Plug.Base which lets me do that.
I can create the user, but not return the struct back to Pow from APIAuthPlug(custom plug to replace Pow.Plug.Session), which won’t create a session for the user automatically.
Another option is to write a custom function, but then I’d be out of Pow’s flow of things and it might get too complicated.
I think both options are bad. I tried to trace the code flow through Pow and it seems like Pow.Plug.create_users calls into Pow.Plug.create/3, which in turn ends up at APIAuthPlug.create.
How should I go about this? Any help is appreciated!
Thanks!
Edit:
I can just copy Pow.Plug.create_user function in my RegistrationController and do something like this…
defmodule RegistrationController do
def create(conn, %{ "user" => params}) do
conn
|> custom_create(params)
|> case do
{:ok, user, conn} ->
send_confirmation_email()
json(conn, %{message: "Please check your email"}
{:error, changeset, conn} -> ....
end
end
# Copied from Pow.Plug.create_user/2
def custom_create(conn, params) do
alias Pow.Plug
config = Plug.fetch_config(conn)
params
|> Pow.Operations.create(config)
end
end
While you can use Pow.Operations.create/2, it makes more sense to just call the context module:
defmodule MyAppWeb.API.V1.RegistrationController do
use MyAppWeb, :controller
alias Ecto.Changeset
alias Plug.Conn
alias MyAppWeb.ErrorHelpers
@spec create(Conn.t(), map()) :: Conn.t()
def create(conn, %{"user" => user_params}) do
user_params
|> Pow.Ecto.Context.create(repo: MyApp.Repo, user: MyApp.Users.User)
|> case do
{:ok, _user} ->
send_confirmation_email()
json(conn, %{message: "Please check your email"}
{:error, changeset} ->
errors = Changeset.traverse_errors(changeset, &ErrorHelpers.translate_error/1)
conn
|> put_status(500)
|> json(%{error: %{status: 500, message: "Couldn't create user", errors: errors}})
end
end
# ...
end
For your use case this would probably be the best. But in the PowEmailConfirmation extension I just delete the session in the controller callback with Pow.Plug.delete/1.
One more question, the API guide says to use PowPersistentSession.Store.PersistentSessionCache in APIAuthPlug to keep the renew_token, but it doesn’t seem to be working anymore? Also, that stuff’s no longer in the docs for 1.0.18.
Should I writing a custom plug using PowPersistentSession.Plug.Base? I don’t think it’s possible to use the Cookie plug for an API.
I ran mix deps.clean and mix deps.get and that seems to have fixed PersistentSessioCache problem. Earlier keys weren’t being persisted, but they’re being persisted correctly now. Not sure what that problem was.
Hi, I’m thinking of building an api using Phoenix Framework for the mobile app, the front end will be written in dart, with the help of flutter framework.
The communication between server and client will be made with Phoenix channels.
I wanted to ask how well does the Pow library play for such cases, it seems more geared to web apps usage, what does is take to make it work for mobile apps backends, did anyone use it similar way, is there a manual, tutorial or github repo to quickly look at the code?
A little example here would be nice too.
I know there are many who have implemented Pow in mobile apps using e.g. Phoenix Channels. The way you need to implement it depends on your particular auth story though.
I do plan eventually to write some documentation for it, but for now there’s this gigantic issue dealing with Phoenix LiveView in particular: https://github.com/danschultzer/pow/issues/271
But in short; you can use the API guide that @dorgan linked to create & authenticate the user. Then you can use the auth token to authorize access in your user socket, which would be almost the same as the logic you see in fetch/2 of the API auth plug.
Thanks a lot, @danschultzer, I’ll dive straight into this!
And yes, I think most common usecases, such as authentication for html app, rest api (aka json api), websocket connections (channels, LiveView, etc) all need to have implementation examples in the docs, I see this is already the case for html and api usage.
Yeah, but it depends how you wish to handle distribution.
You may want to run the MnesiaCache on a separate node, or use a custom MnesiaCache module, since MnesiaCache would override local data with what is in the cluster when joining. You can find more in the docs here: https://hexdocs.pm/pow/1.0.19/Pow.Store.Backend.MnesiaCache.html
I think you misunderstood my question or I am misunderstanding your reply and linked docs.
In my understating Mnesia is used by Pow to persist sessions, and what I am asking is if Pow supports to use Mnesia also to persist the created users, aka when you register for the fist time, because I don’t see this mention anywhere, not even in the linked docs, but I may had misunderstood something.
By the way congrats for the awesome work you have done with Pow
afaik Pow uses ecto - so you can try using https://gitlab.com/patatoid/ecto3_mnesia - you would need to replicate the Pow ecto migrations into a script creating the db tables as per the ecto3_mnesia readme…