# UeberauthCognito

[![Build Status](](

An Ueberauth Strategy for AWS Cognito.

## Installation

Add `:ueberauth` and `:ueberauth_cognito` to your `mix.exs`:

defp deps do
    # ...
    {:ueberauth, "~> 0.6"},
    {:ueberauth_cognito, "~> 0.1"}

Configure Ueberauth to use this strategy:

config :ueberauth, Ueberauth,
  providers: [
    cognito: {Ueberauth.Strategy.Cognito, []}

and configure the required values:

config :ueberauth, Ueberauth.Strategy.Cognito,
  auth_domain: {System, :get_env, ["COGNITO_DOMAIN"]},
  client_id: {System, :get_env, ["COGNITO_CLIENT_ID"]},
  client_secret: {System, :get_env, ["COGNITO_CLIENT_SECRET"]},
  user_pool_id: {System, :get_env, ["COGNITO_USER_POOL_ID"]},
  aws_region: {System, :get_env, ["COGNITO_AWS_REGION"]} # e.g. "us-east-1"

The values can be configured with an MFA, or simply a string.

Add the routes to the router:

scope "/auth", SignsUiWeb do
  pipe_through([:redirect_prod_http, :browser])
  get("/:provider", AuthController, :request)
  get("/:provider/callback", AuthController, :callback)

and create the corresponding controller:

defmodule SignsUiWeb.AuthController do
  use SignsUiWeb, :controller

  def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
    # what to do if sign in fails

  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
    # sign the user in or something.
    # auth is a `%Ueberauth.Auth{}` struct, with Cognito token info
    send_resp(conn, 200, "Welcome, #{auth.uid}")

Note that the entry in the `router` defines the authentication callback URL, and will need to be whitelisted in the AWS Cognito User Pools settings.

## Refreshing access tokens

Cognito supports [using refresh tokens]( to automatically obtain new access tokens for users whose access tokens expire. If your application has a refresh token handy, you can redirect to the callback URL with the `refresh_token` param set, and Ueberauth will attempt to use the given refresh token value to obtain a fresh access token.

The refresh token for an access token is issued at the same time as the access token, and is available in the `Ueberauth.Auth.Credentials` struct. Whether to use refresh tokens, and where to store them if used, is an implementation detail. Your first instinct might be to store them in a cookie, but they can sometimes exceed the maximum possible cookie size. An alternative is to store an identifier (which could be a username, or simply a random nonce) in a cookie, and create a GenServer that maps these identifiers to refresh tokens. This has the advantage of not revealing the refresh tokens to the end user, if this is a consideration.