For handling authentication with Auth0 we will continue to use our existing gems (g5_authenticatable and g5_authenticatable_api.) The g5_authentication_client gem will be removed as it is no longer applicable. In most cases we should only need to install g5_authenticatable. Moving forward with v2 these codebases will be in the g5search github org and once fully released we can depricate or remove the code in the G5 org.
- Update gem version
source 'https://gem.fury.io/g5dev/' do
gem 'g5_authenticatable', '~> 2.0.6.pre.alpha.gem'
end
- Change g5_authenticatable engine namespace to
mount G5Authenticatable::Engine => '/'
- for new install this will be added with the generator
rails g g5_authenticatable:install
- add env vars to secrets.yml file
development:
secret_key_base: ...
auth0_client_id: <%= ENV["AUTH0_CLIENT_ID"] %>
auth0_client_secret: <%= ENV["AUTH0_CLIENT_SECRET"] %>
auth0_domain: <%= ENV["AUTH0_DOMAIN"] %>
- changes for machine to machine token
- Update instances of
G5AuthenticationClient::Client.username_pw_access_token
toG5Authenticatable::Api::Services::AuthClient::fetch_access_token(audience)
- Update instances of
G5AuthenticationClient::AuthToken::do_with_username_pw_access_token
toG5Authenticatable::Api::AuthToken::do_with_access_token(audience)
- Example:
class Something
include G5Authenticatable::Api::AuthToken
def send_payload
# see here for available app names https://www.g5devops.com/apps/
audience = 'app-name'
@response = do_with_access_token(audience) do |token|
HTTParty.post(endpoint,
body: { example: @payload }.to_json,
headers: { 'authorization' => "Bearer #{token}" })
end
end
end
- As conversions are made to fetch the token with the new access_token method, we will also need to adjust how we are sending the token. The gem currently still allows the token to be passed by either an Authorization header,
access_token
query parameter or from warden, but we could potentially run in to issues of hitting the max url length if we continue using the query parameter. For example, this could be a problem in the vendor lead feed, where there are also location urn query params. It is recommended that we convert to using the Authorization header.
Misc.
- access tokens that were previouly accessed from the TokenValidator class can now be accessed from the TokenInfo class.
- example
is nowG5AuthenticatableApi::Services::TokenValidator.new(params, request.headers).access_token
G5AuthenticatableApi::Services::TokenInfo.new(params, request.headers).access_token
As we're going through these apps, I'd like to make sure we think about the session store. The default session store in Rails is the cookie store. This works great for a lot of apps, but not for customer-facing apps. Years ago when we added granular permissions, the session for a size grew for users with many location assignments. It got so big that it went over the limit for a browser cookie's max size (and generated CookieOverflow errors in Rails, which sound delicious but aren't).
So we switched some apps to the
activerecord-session_store
gem. This adds a migration which adds a new table where sessions are stored, and the cookie just holds a key that can get their row back out of the database. But sessions expire and database rows don't. The README for the gem says you need to trim old sessions (and they provide a rake task), but we haven't done that. Apps like the IMC and NAE now have millions of rows for expired sessions.As we're going through these apps, I'd like to make sure we evaluate something like the following:
Are customers logging into the application?
activerecord-session_store
gem. Continue on to the next question.Gemfile
. If it is in theGemfile
and was in use, reverse the installation process in the README. Ensure you generate a new migration to drop the old table.Still have the gem? Ensure there is a daily job that clears out stale sessions!
sidekiq
, use (or install)sidekiq-cron
and have a nightly job to trim the sessions. You can find the code for this in the rake task in the gem.sidekiq
, talk to DevOps about creating a Kubernetes CronJob object to perform this task.