# Simplified GitHub Login for a Ruby Web App

Source: https://www.yegor256.com/2018/06/19/glogin.html

You know what [OAuth](https://en.wikipedia.org/wiki/OAuth)
login is, right? It's when your users click "login"
and get redirected to Facebook, Twitter, Google, or some other
website which then identifies them. Then they go back to your website and you
know who they are. It's very convenient for them. It's convenient for you
too, since you don't need to implement the login functionality and don't
need to keep their credentials in a database. I created a simple
[Ruby gem](https://github.com/yegor256/glogin)
to simplify this operation for GitHub only. Here is how it works.


{% jb_picture_body %}

First, you will have to register your application in GitHub,
as [this page](https://developer.github.com/apps/building-integrations/setting-up-and-registering-oauth-apps/)
explains. This is how it works with
[Sinatra](https://sinatrarb.com/),
but you can do something similar in any framework.

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

```ruby
require 'glogin'
configure do
  set :glogin, GLogin::Auth.new(
    # You get this from GitHub, when you register your
    # web application:
    client_id,
    # Make sure this value is coming from a secure
    # place and is NOT visible in the source code:
    client_secret,
    # This is what you will register in GitHub as an
    # authorization callback URL:
    'https://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:

```ruby
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:
        encryption_secret
      ).to_user
    rescue OpenSSL::Cipher::CipherError => _
      # Nothing happens here, the user is not logged in.
      cookies.delete(:glogin)
    end
  end
end
```

If the `glogin` cookie comes in and contains valid data,
a local variable `@user` will be set to something like this:

```ruby
{ login: 'yegor256', avatar: 'http://...' }
```

Next, we need a URL for GitHub OAuth callback:

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

Finally, we need a logout URL:

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

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

```ruby
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 will be disabled:
whatever comes from the cookie will be trusted. For testing
it will be convenient to provide a user name in a query string, like this:

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

To enable that, it's recommended you add this line (see how
it works in [zold-io/wts.zold.io](https://github.com/zold-io/wts.zold.io)):

```ruby
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](https://github.com/yegor256/sixnines),
[0pdd](https://github.com/yegor256/0pdd),
and [Zold](https://github.com/zold-io/wts.zold.io)
web apps on top of Sinatra (all open source).
