riverrun / openmaize

No longer maintained - was an Authentication library for Plug-based applications in Elixir
Other
206 stars 30 forks source link

Tip on how to use openmaize without a "role" column (coming from Rails & devise) #46

Closed thbar closed 8 years ago

thbar commented 8 years ago

Hi there! First, thanks for openmaize, which I'm starting to use to achieve authentication against an existing Rails/devise database (gradual rewrite of app from Rails to Phoenix).

It took me a bit of time to figure this out so I thought I'd share it here - maybe this is worth adding to the readme (e.g. "migrating from Rails & devise" section), since I suspect more people will do this in the upcoming months.

The first obvious steps to get this working were in the config:

config :openmaize,
  # matches devise db convention
  hash_name: :encrypted_password

and in my controller:

  plug Openmaize.Login, [
    db_module: MyApp.OpenmaizeEcto,
    # matches devise db convention
    unique_id: :email
  ] when action in [:login_user]

That was the easy part; the harder one was around the role column.

The database users table hasn't got a role column in devise (at least not by default). Initially I just tweaked the code in web/controllers/authorize/ to fix pattern matching againstrole(which didn't work), butcurrent_userwasn't set after that. I dig into openmaize-jwt and ended up seeing that because therole` key was missing, I got an "incomplete token" error.

Ultimately I used a virtual field with a default value for role, which seems to work fine:

  schema "users" do
    field :email, :string
    # snip
    field :encrypted_password, :string
    timestamps inserted_at: :created_at
    # this seems to work nicely
    field :role, :string, virtual: true, default: "user"
  end

Hope this helps others :-)

riverrun commented 8 years ago

Thanks for the feedback. This is really useful because I don't know Devise that well myself, but I know that there will be a lot of developers out there who will come to Openmaize from Devise and Ruby. It's also interesting to see how you're using it - especially as I thought that roles were so central :) I'll work on adding something to the docs about this.

thbar commented 8 years ago

Great, thanks for considering this! Hit me up if you have any question, and I'll make sure to share more here if I have more questions.

jaimeiniesta commented 8 years ago

Thanks for sharing this @thbar - I'm also migrating a Rails app to Phoenix using Openmaize, but in my case it's a complete rewrite so it was OK for me just to drop the role column there, even though I don't use roles in my app.

I don't see roles as a central part of an authentication library, but maybe this is because I come from Devise, that doesn't implement roles (you manage them at a different level).

riverrun commented 8 years ago

I've decided to remove the need for a user role, and so in the latest versions of Openmaize (1.0.0-beta.4) and OpenmaizeJWT (0.12), I've removed the need for the role to be set, so you can create and verify tokens without a user role being specified. I'm also going to make a few changes to the Authorize modules that are created by the mix generators - to make it more clear how you can use / customize them with or without user roles.

riverrun commented 8 years ago

A couple of updates:

  1. From version 2.0.0, Openmaize uses cookie-based sessions for authentication.
  2. If you generate the database files using mix openmaize.gen.ectodb, there is no need to add db_module: OpenmaizeEcto to the call to plug. This means that the initial example you gave can now be written as plug Openmaize.Login, [unique_id: :email] when action in [:login_user].