Skip to content

yegor256/glogin

Repository files navigation

OAuth Login via GitHub Made Simple

DevOps By Rultor.com We recommend RubyMine

rake PDD status Gem Version Maintainability Test Coverage Yard Docs Hits-of-Code License

This simple gem helps you enable login/logout through GitHub OAuth for your web application. This is how it works with Sinatra, but you can do something similar in any framework.

Read this blog post to get the idea: Simplified GitHub Login for a Ruby Web App

First, somewhere in the global space, before the app starts:

require 'glogin'
configure do
  set :glogin, GLogin::Auth.new(
    # Make sure these values are coming from a secure
    # place and are not visible in the source code:
    client_id, client_secret,
    # This is what you will register in GitHub as an
    # authorization callback URL:
    'http://www.example.com/github-callback'
  )
end

Next, for all web pages we need to parse a cookie, if it exists, and convert it into a user:

require 'sinatra/cookies'
before '/*' do
  if cookies[:glogin]
    begin
      @user = GLogin::Cookie::Closed.new(
        cookies[:glogin],
        # This must be some long text to be used to
        # encrypt the value in the cookie.
        secret
      ).to_user
    rescue GLogin::Codec::DecodingError => _
      # Nothing happens here, the user is not logged in.
      cookies.delete(:glogin)
    end
  end
end

If the glogin cookie is coming in and contains valid data, a local variable @user is set to something like this:

{ 'id' => '526301', 'login' => 'yegor256', 'avatar' => 'http://...' }

If the secret is an empty string, the encryption is disabled.

Next, we need a URL for GitHub OAuth callback:

get '/github-callback' do
  cookies[:glogin] = GLogin::Cookie::Open.new(
    settings.glogin.user(params[:code]),
    # The same encryption secret that we were using above:
    secret
  ).to_s
  redirect to('/')
end

Finally, we need a logout URL:

get '/logout' do
  cookies.delete(:glogin)
  redirect to('/')
end

It is recommended to provide the third "context" parameter to GLogin::Cookie::Closed and GLogin::Cookie::Open constructors, in order to enforce stronger security. The context may include the User-Agent HTTP header of the user, their IP address, and so on. When anything changes on the user side, they are forced to re-login.

One more thing is the login URL you need for your front page. Here it is:

settings.glogin.login_uri

For unit testing, you can just provide an empty string as a secret for GLogin::Cookie::Open and GLogin::Cookie::Closed and the encryption is disabled: whatever comes from the cookie is trusted. For testing it is convenient to provide a user name in a query string, like:

http://localhost:9292/?glogin=tester

To enable that, it's recommended to add this line (see how it works in zold-io/wts.zold.io):

require 'sinatra/cookies'
before '/*' do
  cookies[:glogin] = params[:glogin] if params[:glogin]
  if cookies[:glogin]
    # same as above
  end
end

I use this gem in sixnines and 0pdd web apps (both open source), on top of Sinatra.

Also, you can use GLogin::Codec just to encrypt/decrypt a piece of text:

require 'glogin/codec'
codec = GLogin::Codec.new('the secret')
encrypted = codec.encrypt('Hello, world!')
decrypted = codec.decrypt(encrypted)

How to contribute

Read these guidelines. Make sure your build is green before you contribute your pull request. You need to have Ruby 2.3+ and Bundler installed. Then:

bundle update
bundle exec rake

If it's clean and you don't see any error messages, submit your pull request.

About

Login/logout via GitHub OAuth for your Ruby web app

Topics

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •  

Languages