{"id":15048340,"url":"https://github.com/github/oauth-ruby-quickstart","last_synced_at":"2025-10-04T08:31:53.233Z","repository":{"id":65974869,"uuid":"134874510","full_name":"github/OAuth-Ruby-Quickstart","owner":"github","description":"Starter code and quickstart guide for a GitHub OAuth App in Ruby","archived":true,"fork":false,"pushed_at":"2019-01-11T11:43:51.000Z","size":20,"stargazers_count":18,"open_issues_count":1,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-09-30T00:22:26.276Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://developer.github.com","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/github.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-25T15:32:55.000Z","updated_at":"2024-09-29T01:52:10.000Z","dependencies_parsed_at":"2023-02-19T18:01:07.483Z","dependency_job_id":null,"html_url":"https://github.com/github/OAuth-Ruby-Quickstart","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2FOAuth-Ruby-Quickstart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2FOAuth-Ruby-Quickstart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2FOAuth-Ruby-Quickstart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/github%2FOAuth-Ruby-Quickstart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/github","download_url":"https://codeload.github.com/github/OAuth-Ruby-Quickstart/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235232745,"owners_count":18957057,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T21:11:01.341Z","updated_at":"2025-10-04T08:31:47.958Z","avatar_url":"https://github.com/github.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"## About this Quickstart Guide\nThis is a quickstart guide to GitHub OAuth authentication using:\n- Ruby\n- The [Sinatra](http://sinatrarb.com) web framework\n- [Octokit](https://github.com/octokit/octokit.rb) - a Ruby client for the GitHub [REST API](https://github.com.) (makes interacting with GitHub data easier)\n\nTo demonstrate the OAuth process, we're going to:\n1) Set up a basic web server with Sinatra\n2) Register a new OAuth Application on GitHub.com\n3) Authenticate a user into our Sinatra app using GitHub's OAuth API\n4) Use Octokit to retrieve this user's information from GitHub\n\n## 1) Sinatra Webserver Setup\nFirst, go ahead and clone the starter code from the [OAuth Ruby Quickstart Guide](https://github.com/github/OAuth-Ruby-Quickstart) repository.\n\nThis repository contains 3 files that we'll be working with:\n\n`server.rb` - Our Sinatra webserver\n\n`views/index.erb` - The webpage users will see before 'Signing in with GitHub'\n\n`views/profile.erb` - The webpage users will see _after_ authenticating with GitHub OAuth. This page will display their profile photo, along with other user information\n\n_P.S._([erb](https://ruby-doc.org/stdlib-2.5.1/libdoc/erb/rdoc/ERB.html) is a Ruby templating language which allows us to build HTML pages and pass in application data to be displayed on the page)\n\n\nTo fire up our webapp, open a terminal and run the following command from the project directory.\n```\n$ ruby server.rb \n```\n\nYou should see a message that **'Sinatra has taken the stage'**\n\n![sinatra_on_stage](https://user-images.githubusercontent.com/3988879/40750699-5cb07faa-6425-11e8-829b-d2ffe7620871.png)\n\nWe can now visit [http://localhost:4567](http://localhost:4567) to see our webpage.\n\nYou should see something like this:\n\n![localhost:4567](https://user-images.githubusercontent.com/3988879/40741163-fee7adca-6407-11e8-9465-9cbdb2072286.png)\n\nOur Sinatra app is up and running, but clicking that green **Sign In** button won't work yet. First, we need to register a new GitHub OAuth Application.\n\n\n## 2) Register a new GitHub OAuth Application\nHead on over to your [Developer Settings](https://github.com/settings/developers) and register a new OAuth Application.\n\n![screen shot 2018-05-25 at 4 23 36 pm](https://user-images.githubusercontent.com/3988879/40568485-0f8fb498-6038-11e8-8405-25142babaac8.png)\n\n\nYou'll find the following fields:\n**Application name** - This must be unique among all GitHub OAuth Applications.\n**Homepage URL** - If you don't have a homepage for your application yet, just use your GitHub profile: `https://github.com/\u003cYOUR_USER_NAME\u003e` (don't forget the `https://`).\n**Application description** - Explain to future users what this OAuth Application is used for.\n**Authorization callback URL** - GitHub needs to know where to redirect users after a successful OAuth authorization. For this app, the user should be redirected to the `/profile` view in our `server.rb` file. Since we're still working locally, we can actually use the localhost url from step #1: `http://localhost:4567/profile`.\n\n\n## 3) Authenticate a User with GitHub’s OAuth API\nNow for the fun stuff.\n\nAfter registering your OAuth Application, you should see your Client ID and Client Secret. They'll look something like this:\n\n![Client ID and Secret](https://user-images.githubusercontent.com/3988879/40741261-569e00d2-6408-11e8-96e4-3b454b5d7cbe.png)\n\nCopy the Client ID and Client Secret into their respective places in the `server.rb` file.\n\nGiven the example above, the code would look like this:\n\n![Client ID \u0026 Secret](https://user-images.githubusercontent.com/3988879/40741287-6c5267f6-6408-11e8-9d74-b5d1fe3f7232.png)\n\nWith that set up, we're ready to authenticate a user with GitHub's OAuth API.\n\nWith the Sinatra app running, go ahead and visit [localhost:4567](http://localhost:4567) again. This time, clicking the **Sign In with GitHub** button should take you to an authorization page:\n\n![authorization](https://user-images.githubusercontent.com/3988879/40750372-4c5ae452-6424-11e8-8eda-67d03ca548fc.png)\n\nThis is where users grant your OAuth Application permission to access their data. As you can see, we're only requesting public data right now.\n\n##### What happened here?\nIf you look at the URL in the address bar, you'll see your Client ID. On the previous page, the **Sign In with GitHub** button was in fact a link to an OAuth Authorization page, with your Client ID as a parameter. Sinatra built this link for us when we passed the `CLIENT_ID` into the index.erb template on line 24 of `server.rb`. Sinatra then interpolated our Client ID into the OAuth API link on line 15 of `index.erb`.\n\nGo ahead and Authorize the Application access to your GitHub account data, and you should be redirected to your callback page: `/profile`.\n\n![success](https://user-images.githubusercontent.com/3988879/40751094-f98ceea2-6426-11e8-915a-c44e0f38cfb6.png)\n\nAfter a successful Application authorization, GitHub provides us with a temporary *authorization grant code* (see it in the URL up there?). We need to `POST` this code to the's `/login/oauth/access_token` endpoint to recieve an *access_token* The access token is what grants us access to the account data that we want to display.\n\nTo simplify the process of `POST`ing the authorization grant code back to GitHub, we'll use the [rest-client](https://github.com/rest-client/rest-client) Ruby gem.\n\nFirst, let's update our `/profile` view to retrieve the temporary authorization grant code. We'll use Sinatra's built in webserver interface, [Rack](https://rack.github.io/) to grab the code from the session data.\n\n``` ruby\nget '/profile' do\n    # Retrieve temporary authorization grant code\n    session_code = request.env['rack.request.query_hash']['code']\n    \n    erb :profile\nend\n```\n\nNow that we have the authorization grant code, let's use `rest-client` to `POST` it back to GitHub along with our `CLIENT_ID` and `CLIENT_SECRET` in exchange for our `access_token`.\n\nThe `https://github.com/login/oauth/access_token` endpoint expects the following parameters:\n\nName | Type | Description\n-- | -- | --\n`client_id` | `string` | __Required.__ Your GitHub OAuth Application Client ID\n`client_secret` | `string` | __Required.__ Your GitHub OAuth Application Client Secret\n`code` | `string` | __Required.__ The authorization grant code returned after Application authorization\n\n\nLet's also use the request header `:accept` to let the API know that we'd like a `JSON` formatted response.\n\n``` ruby\nget '/profile' do\n    # Retrieve temporary authorization grant code\n    session_code = request.env['rack.request.query_hash']['code']\n    \n    # POST Auth Grant Code + CLIENT_ID/SECRECT in exchange for our access_token\n    response = RestClient.post('https://github.com/login/oauth/access_token',\n                    # POST payload\n                    {:client_id =\u003e CLIENT_ID\n                    :client_secret =\u003e CLIENT_SECRET\n                    :code =\u003e session_code},\n                    # Request header for JSON response\n                    :accept =\u003e :json)\n    \n    erb :profile\nend\n```\n\nThe API's response to our `POST` request will include the access token in a field called `access_token` in the `response` variable. Now we just need to parse out the access token.\n\n``` ruby\n    #Parse access_token from JSON response\n    access_token = JSON.parse(response)['access_token']\n```\n\n## 4) Use Octokit to Access User Data\n\nNow that we finally have our access token, we can start acessing user data via the GitHub API. Instead of manually calling / handling our own REST request / responses to the API, we can save some time and effort by using GitHub's official Ruby library, [Octokit](http://octokit.github.io/octokit.rb/).\n\nFirst, we need initialize the Octokit client by passing it our access token `Octokit::Client.new(:access_token =\u003e access_token)`. After that, the user data associated with our `access_token` is available as `client.user`. We can now access any of the [user data properties](https://developer.github.com/v3/users/#get-the-authenticated-user) available from the v3 REST API.\n\nHere is the entire function, with the call to Octokit:\n\n``` ruby\nget '/profile' do\n    # Retrieve temporary authorization grant code\n    session_code = request.env['rack.request.query_hash']['code']\n    \n    # POST Auth Grant Code + CLIENT_ID/SECRECT in exchange for our access_token\n    response = RestClient.post('https://github.com/login/oauth/access_token',\n                    # POST payload\n                    {:client_id =\u003e CLIENT_ID,\n                    :client_secret =\u003e CLIENT_SECRET,\n                    :code =\u003e session_code},\n                    # Request header for JSON response\n                    :accept =\u003e :json)\n    \n    # Parse access_token from JSON response\n    access_token = JSON.parse(response)['access_token']\n    \n    # Initialize Octokit client with user access_token\n    client = Octokit::Client.new(:access_token =\u003e access_token)\n    \n    # Create user object for less typing\n    user = client.user\n    \n    # Access user data\n    profile_data = {:user_photo_url =\u003e user.avatar_url,\n                    :user_login =\u003e user.login,\n                    :user_name =\u003e user.name,\n                    :user_id =\u003e user.id }       \n    \n    # Render profile page, passing in user profile data to be displayed\n    erb :profile, :locals =\u003e profile_data\nend\n```\n\nAll of the template [locals](http://sinatrarb.com/intro.html) we'd like to use are packaged up in `profile_data` and will be availble on the `profile.erb` page.\n\nNow we just need to add in the erb partials in `profile.erb` to display the data.\n\n``` html\n\u003cbody\u003e\n    \u003cdiv class=\"p-5\"\u003e\n        \u003cdiv class=\"blankslate blankslate-narrow p-9\"\u003e\n            \u003cimg src=\"\u003c%= user_photo_url %\u003e\" /\u003e\n            \u003ch3\u003e\n                Hey, \u003ca href=\"\u003c%= user_url %\u003e\"\u003e@\u003c%= user_login %\u003e\u003c/a\u003e!\n            \u003c/h3\u003e\n            \u003cp\u003e\n                You are GitHub user #\u003c%= user_id %\u003e\n            \u003c/p\u003e\n            \u003cp class=\"text-gray alt-text-small\"\u003e\n                Click \u003ca href=\"https://api.github.com/users/\u003c%= user_login %\u003e\"\u003ehere\u003c/a\u003e to see all of\n                \u003cbr\u003eyour public profile data\n            \u003c/p\u003e\n        \u003c/div\u003e\n    \u003c/div\u003e\n\u003c/body\u003e\n```\n\nThe final result should look something like this:\n\u003cimg width=\"969\" alt=\"complete\" src=\"https://user-images.githubusercontent.com/3988879/41005787-bc465d10-68d3-11e8-8b96-eac7b78de8dc.png\"\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Foauth-ruby-quickstart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgithub%2Foauth-ruby-quickstart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgithub%2Foauth-ruby-quickstart/lists"}