Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
OmniAuth strategy for authenticating Heroku users.
Mount this with your Rack application (be it Rails or Sinatra) to simplify the OAuth flow with Heroku.
This is intended for apps already using OmniAuth, for apps that authenticate against more than one service (eg: Heroku and GitHub), or apps that have specific needs on session management. If your app doesn't fall in any of these you should consider using Heroku Bouncer instead.
OmniAuth works as a Rack middleware. Mount this Heroku adapter with:
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET")
end
Obtain a HEROKU_OAUTH_ID
and HEROKU_OAUTH_SECRET
by creating a client with
the Heroku OAuth CLI plugin.
Your Heroku OAuth client should be set to receive callbacks on
/auth/heroku/callback
.
Initiate the OAuth flow sending users to /auth/heroku
.
Once the authorization flow is complete and the user is bounced back to your
application, check env["omniauth.auth"]["credentials"]
. It contains both a
refresh token and an access token (identified just as "token"
) to the
account.
We recommend using this access token together with the Heroku Platform API gem to make API calls on behalf of the user.
Refer to the examples below to see how these work.
If you want this middleware to fetch additional Heroku account information like
the user email address and name, use the fetch_info
option, like:
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
fetch_info: true
end
This sets name and email in the omniauth auth hash. You can access
it from your app via env["omniauth.auth"]["info"]
.
It will also add additional Heroku account info to
env["omniauth.auth"]["extra"]
.
Heroku supports different OAuth scopes. By default this strategy will request global access to the account, but you're encouraged to request for less permissions when possible.
To do so, configure it like:
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
scope: "identity"
end
This will trim down the permissions associated to the access token given back to you.
The OAuth scope can also be decided dynamically at runtime.
For example, you could use a scope
parameter from the request, if it exists, with a default value if it does not:
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
scope: ->(env) { Rack::Request.new(env).params["scope"] || "identity" }
end
Versions before 1.0
allowed you to pass :scope
option as a block, just as today.
However, that block received a Rack::Request
instance, rather than the Rack
env
.
If you used the Rack::Request
argument in your :scope
block you can update your code to create a new instance, from the env
.
For example, < 1.0
code that looked like this:
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
scope: ->(request) { request.params["scope"] }
end
need to be updated to something like this:
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET"),
scope: ->(env) { Rack::Request.new(env).params["scope"] }
end
class Myapp < Sinatra::Application
use Rack::Session::Cookie, secret: ENV.fetch("SESSION_SECRET")
use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET")
end
get "/" do
redirect "/auth/heroku"
end
get "/auth/heroku/callback" do
access_token = env["omniauth.auth"]["credentials"]["token"]
# DO NOT store this token in an unencrypted cookie session
# Please read "A note on security" below!
heroku = PlatformAPI.connect_oauth(access_token)
"You have #{heroku.app.list.count} apps"
end
end
Note that we're explicitly calling Rack::Session::Cookie
with a secret. Using
enable :sessions
is not recommended because the secret is generated randomly,
and not reused across processes – so your users can lose their session whenever
your app restarts.
Under config/initializers/omniauth.rb
:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :heroku, ENV.fetch("HEROKU_OAUTH_ID"), ENV.fetch("HEROKU_OAUTH_SECRET")
end
Then add to config/routes.rb
:
Example::Application.routes.draw do
get "login" => "sessions#new"
get "/auth/:provider/callback" => "sessions#create"
end
Controller support:
class SessionsController < ApplicationController
def new
redirect_to "/auth/heroku"
end
def create
access_token = request.env["omniauth.auth"]["credentials"]["token"]
# DO NOT store this token in an unencrypted cookie session
# Please read "A note on security" below!
heroku = PlatformAPI.connect_oauth(access_token)
@apps = heroku.app.list
end
end
And view:
<h1>Your Heroku apps:</h1>
<ul>
<% @apps.each do |app| %>
<li><%= app["name"] %></li>
<% end %>
</ul>
Make sure your cookie session is encrypted before storing sensitive information on it, like access tokens. encrypted_cookie is a popular gem to do that in Ruby.
Both Rails and Sinatra take a cookie secret, but that is only used to protect against tampering; any information stored on standard cookie sessions can easily be read from the client side, which can be further exploited to leak credentials off your app.
Released under the MIT license.
Created by Pedro Belo.
FAQs
Unknown package
We found that omniauth-heroku demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.