Git Product home page Git Product logo

passport's Introduction

Build Status Coverage Status

Passport

Passport provides authentication for Phoenix applications.

How to use?

  • add passport to your phoenix project's mix.exs
defp deps do
  ...
   {:passport, "~> 0.0.1"}
  ...
end
  • run mix deps.get, compile to download and compile the dependency.

  • create an ecto model for your user with fields email and crypted_password. You may add additional fields if you need. Typically you can create a model in phoenix using the below command mix phoenix.gen.model YourApp.User users email crypted_password

  • edit your project's config/config.exs file and configure passport. Passport basically needs to know the Repo name and the user module name.

config :passport,
  repo: YourApp.Repo,
  user_class: YourApp.User,

Routes

Passport does not create routes or controllers for you. Rather, it only provides easy to use module and methods that you can use in your own router and controller. Overriding default routes and controllers have been one of the pain that I wanted to avoid in passport.

Add the following routes to your router.ex. Change the path/controller name as per your application's needs.

scope "/", YourApp do
...
  get "/login", SessionController, :new
  post "/login", SessionController, :create
  get "/logout", SessionController, :delete

  get "/signup", RegistrationController, :new
  post "/signup", RegistrationController, :create
end

Here we assume that

SessionController

  • login form is shown in the url '/login' (GET)
  • login form gets submitted to the url '/login' (POST)
  • user get logout when visiting the path '/logout' (GET)

RegistrationController

  • registration form is shown in the url '/signup' (GET)
  • registration form gets submitted to the url '/signup' (POST)

Sample session_controller.ex

defmodule YourApp.SessionController do
  use YourApp.Web, :controller
  alias Passport.SessionManager
  alias YourApp.User

  plug :action

  def new(conn, _params) do
    render conn, "new.html"
  end

  def create(conn, %{"session" => session_params}) do
    case SessionManager.login(conn, session_params) do
      {:ok, conn, user} ->
        conn
        |> put_flash(:info, "Login succesful.")
        |> redirect(to: page_path(conn, :index))
       {:error, conn} ->
         conn
         |> put_flash(:info, "Email or password incorrect.")
         |> redirect(to: page_path(conn, :index))
    end
  end

  def delete(conn, _params) do
    SessionManager.logout(conn)
    |> put_flash(:info, "Logged out succesfully.")
    |> redirect(to: page_path(conn, :index))
  end

end

Sample registration_controller.ex

defmodule YourApp.RegistrationController do
  use YourApp.Web, :controller

  alias YourApp.User
  alias Passport.RegistrationManager

  plug :action

  def new(conn, _params) do
    conn
    |> put_session(:foo, "bar")
    |> render("new.html")
  end

  def create(conn, %{"registration" => registration_params}) do
    case RegistrationManager.register(registration_params) do
      {:ok} -> conn
         |> put_flash(:info, "Registration success")
         |> redirect(to: page_path(conn, :index))
      _ -> conn
         |> put_flash(:info, "Registration failed")
         |> redirect(to: page_path(conn, :index))
    end
  end

end

Sample session/new.html for displaying login form

<%= form_for @conn, session_path(@conn, :create), [name: :session], fn f -> %>
  <div class="form-group">
    <label>Email</label>
    <%= text_input f, :email, class: "form-control" %>
  </div>

  <div class="form-group">
    <label>Password</label>
    <%= text_input f, :password, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= submit "Login", class: "btn btn-primary" %>
  </div>
<% end %>

Sample registration/new.html for displaying login form

<%= form_for @conn, registration_path(@conn, :create), [name: :registration], fn f -> %>
  <div class="form-group">
    <label>Email</label>
    <%= text_input f, :email, class: "form-control" %>
  </div>

  <div class="form-group">
    <label>Password</label>
    <%= text_input f, :password, class: "form-control" %>
  </div>

  <div class="form-group">
    <%= submit "Signup", class: "btn btn-primary" %>
  </div>
<% end %>

Convenient Shorthands

Passport allows to check if an user is signed in or not. You can import the following in web.ex

def view do
    quote do
      ...
      import Passport.SessionManager, only: [current_user: 1, logged_in?: 1]
      ...
    end
end

Then inside your views you can call both current_user and logged_in? as below:

<%= if logged_in?(@conn) do %>
  <%=  current_user(@conn).email %>
<% end %>

Authentication in Controllers

Use AuthenticationPlug in a contoller to declare Passport's behavior.

...
alias Passport.AuthenticationPlug

plug AuthenticationPlug, [only: [:dashboard, :admin], flash_msg: "You're not allowed!", redirect_to: "/login"]
plug :action
...

AuthenticationPlug will take the following options:

  • :only (array of atoms matching the controller actions to authenticate)
  • :except (array of atoms matching controller actions to not authenticate)
  • :flash_msg (string containing the flash message when a login isn't successful)
  • :redirect_to (string containing the uri to redirect to when a login isn't successful)

Defaults to authenticating all controllers with a message of "You must be logged in." and a redirect to "/login"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.