expected v0.1.1 Expected.Plugs View Source
Plugs for registering logins and authenticating persistent cookies.
Requirements
For the plugs in this module to work, you must plug Expected
in your
endpoint:
plug Expected
As Expected
calls Plug.Session
itself, you must not plug it in your
endpoint. You must however configure the session in the :expected
configuration:
config :expected,
store: :mnesia,
table: :logins,
auth_cookie: "_my_app_auth",
session_store: PlugSessionMnesia.Store, # For instance.
session_cookie: "_my_app_key" # The Plug.Session `:key` option.
For the login registration to work, Expected needs to get the session ID from the session cookie. You must use a session store that stores the session server-side and uses the cookie to store the session ID.
Link to this section Summary
Link to this section Functions
authenticate(Plug.Conn.t(), keyword()) :: Plug.Conn.t()
Authenticates a connection.
Session authentication
This plug first checks if the session is already authenticated. It does so by
reading the :authenticated
field in the session. If it is true
, it assigns
:authenticated
and :current_user
in the conn
according to their value
in the session.
The names of these fields can be changed by setting the corresponding options:
conn
|> authenticate(authenticated: :logged_in, current_user: :user_id)
They can also be set application-wide in the configuration:
config :expected,
...
plug_config: [authenticated: :logged_in, current_user: :user_id]
Cookie authentication
If the session is not yet authenticated, this plug checks for an authentication cookie. By default, it is valid for 90 days after the last successful authentication. You can change this in the application configuration:
config :expected,
...
cookie_max_age: 86_400 # Set to one day, for example.
Alternatively, you can set it locally:
conn
|> authenticate(cookie_max_age: 86_400)
Alerts
For security purpose, an authentication cookie can be used only once. If an
authentication cookie is re-used, conn.assigns.unexpected_token
is set to
true
and the session is not authenticated. You can check this value using
Expected.unexpected_token?/1
and accordingly inform the user of a possible
malicious access.
User loading
After a successful cookie authentication, the :current_user
field in both
the session and the conn
assigns is set to an Expected.NotLoadedUser
,
featuring the user’s username:
%Expected.NotLoadedUser{username: "user"}
You should load this user from the database in another plug following this one if the session has been authenticated.
logout(Plug.Conn.t(), keyword()) :: Plug.Conn.t()
Logs a user out.
This plug deletes the login and its associated session from the stores and their cookies. If there is no authentication cookie, it does nothing.
register_login(Plug.Conn.t(), keyword()) :: Plug.Conn.t()
Registers a login.
Requirements
This plug expects that the session contains a :current_user
key featuring a
:username
field:
conn
|> put_session(:current_user, %User{username: "user", name: "A User"})
|> register_login()
The names of these fields can be changed by setting the corresponding options:
conn
|> put_session(:logged_in_user, %User{user_id: "user", name: "A User"})
|> register_login(current_user: :logged_in_user, username: :user_id)
They can also be set application-wide in the configuration:
config :expected,
...
plug_config: [current_user: :logged_in_user, username: :user_id]
Authentication cookie
Authentication information is stored in a cookie. By default, it is valid for 90 days after the last successful authentication. You can change this in the application configuration:
config :expected,
...
cookie_max_age: 86_400 # Set to one day, for example.
Alternatively, you can set it locally:
conn
|> put_session(:current_user, %User{username: "user", name: "A User"})
|> assign(:persistent_login, true)
|> register_login(cookie_max_age: 86_400)