Omniauth::Cognito::Oauth2
Oauth2 strategy for AWS Cognito
Installation
Add this line to your application's Gemfile:
gem 'omniauth-cognito-oauth2'
Then bundle install
Setup
You will need:
- an AWS Cognito user pool
- a domain setup for your user pool
- an App Client set up for your user pool, exposing at least
openid
andemail
. (Don't set up your App Client with a 'Client Secret' because at the moment they don't work and won't allow you to authenticate.) - a config variable on your dev machine which contains your domain - something like
COGNITO_USER_POOL_DOMAIN=https://your_user_pool_domain.auth.us-west-1.amazoncognito.com
for your variable, and thenRails.configuration.local_settings['COGNITO_USER_POOL_DOMAIN']
in your code (if using Rails of course) - a config variable on your dev machine which contains your App Client ID - something like
COGNITO_CLIENT_ID=your_app_client_id
for your variable, and thenRails.configuration.local_settings['COGNITO_CLIENT_ID']
in your code (if using Rails of course)
Usage
Here's an example for adding the middleware to a Rails app in config/initializers/omniauth.rb
:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :cognito_oauth2, 'MY_COGNITO_CLIENT_ID', scope: [:openid, :email],
setup: lambda{ |env|
env['omniauth.strategy'].[:client_options].site = 'MY_COGNITO_USER_POOL_DOMAIN'
}
end
Since Cognito has many different client sites, we are using a lambda to dynamically set the site that you wish to authenticate against. This will be the domain you have setup for your user pool. There is more info in the Authorization Code Grant section in the AWS docs here.
You can now access the OmniAuth Cognito OAuth2 URL: /auth/cognito_oauth2
Usage (Devise)
First define your client id and user pool domain in config/initializers/devise.rb
.
config.omniauth :cognito_oauth2, 'MY_COGNITO_CLIENT_ID', scope: [:openid, :email],
setup: lambda{ |env|
env['omniauth.strategy'].[:client_options].site = 'MY_COGNITO_USER_POOL_DOMAIN'
}
NOTE: If you are using this gem with devise with above snippet in config/initializers/devise.rb
then do not create config/initializers/omniauth.rb
which will conflict with devise configurations.
Then add the following to 'config/routes.rb' so the callback routes are defined.
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
Make sure your model is omniauthable. Generally this is "/app/models/user.rb"
devise :omniauthable, omniauth_providers: [:cognito_oauth2]
Then make sure your callbacks controller is setup.
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def cognito_oauth2
@user = User.from_omniauth(request.env["omniauth.auth"])
if @user.persisted?
sign_in_and_redirect @user, event: :authentication
(:notice, :success, kind: "Cognito") if
else
# session["devise.cognito_data"] = request.env["omniauth.auth"].except("extra", "provider") # causes cookie overflow - consider creating a session table in your DB to store large session info https://stackoverflow.com/questions/9473808/cookie-overflow-in-rails-application
(:alert, :failure, kind: "Cognito")
redirect_to new_user_session_path
end
end
def failure
redirect_to new_user_session_path
end
end
and bind to or create the user
def self.from_omniauth(auth)
where(email: auth.info.email, uid: auth.uid, provider: "cognito_oauth2").first_or_create! do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.provider = "cognito_oauth2"
user.uid = auth.uid
end
end
Devise will automatically generate a link for you on their default signup/login view, but you can make your own like this if necessary:
<%= link_to "Sign in with Cognito", user_cognito_oauth2_omniauth_authorize_path %>
<%# Devise prior 4.1.0: %>
<%= link_to "Sign in with Cognito", user_omniauth_authorize_path(:cognito_oauth2) %>
An overview is available at https://github.com/plataformatec/devise/wiki/OmniAuth:-Overview
Configuration
You can configure several options, which you pass in to the provider
method via a hash:
scope
: A comma-separated list of permissions you want to request from the user. See the AWS Cognito docs for a full list of available permissions. Caveats:- The
openid
andemail
scopes are used by default. By defining your ownscope
, you override these defaults.
- The
redirect_uri
: Override the redirect_uri used by the gem.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://gitlab.com/felixfortis/omniauth-cognito-oauth2.
License
The gem is available as open source under the terms of the MIT License.