Github get client id and secret

GitHub is a web-based version control repository with around 20 million users across the planet. With 75 million repositories it is the world’s largest host of source codes. To provide an intuitive user experience to the GitHub users on your store, you may want to integrate a GitHub social login. Well, this is a good idea. 20 million users are not a few users, it’s huge. Your online customers are more likely to have an account on GitHub. So, offering GitHub social login option is a good idea to boost customer registration. For this social login integration, GitHub API detail, Client ID and Client Secret is required.
So, to achieve this improved UX, you will require Knowband’s social login module available for various platforms like Prestashop, Opencart and Magento and the following GitHub API details:
- GitHub Client ID and
- GitHub Client Secret
To get these details you must follow these quick steps:
Steps to get GitHub Client ID, Client Secret
Step 1: First of all you need to visit the GitHub Developer website to get these details.
Step 2: It will ask you to login to your GitHub account first. After logging in click on the Applications tab.
Step 3: Here you will see two tab- Authorized Applications and Developer applications. Click on the Developers applications, You will see the following screen. Enter the details as shown in the image below:
Enter Application Name, You Home-Page URL and redirect URL in Authorization call back URL.
Step 4: Hit the “Register application” button after filling all the required details.
Step 5: The next interface will show the Client ID and Client Secret details.
Step 6: Copy these details and keep it with you. You can use these details in your Social login module if it supports Social Login via GitHub.
For example, in Social Loginizer module (PrestaShop, OpenCart, or Magento), the interface to enter the GitHub API details looks something this:
Liked This? You’ll Like These Too
In this section, we’re going to focus on the basics of authentication. Specifically,we’re going to create a Ruby server (using Sinatra) that implementsthe web flow of an application in several different ways.
You can download the complete source code for this project from the platform-samples repo.
Registering your app
First, you’ll need to register your application. Everyregistered OAuth application is assigned a unique Client ID and Client Secret.The Client Secret should not be shared! That includes checking the stringinto your repository.
You can fill out every piece of information however you like, except theAuthorization callback URL. This is easily the most important piece to settingup your application. It’s the callback URL that GitHub returns the user to aftersuccessful authentication.
Since we’re running a regular Sinatra server, the location of the local instanceis set to http://127.0.0.1:4567
. Let’s fill in the callback URL as http://127.0.0.1:4567/callback
.
Accepting user authorization
Deprecation Notice: GitHub will discontinue authentication to the API using query parameters. Authenticating to the API should be done with HTTP basic authentication. Using query parameters to authenticate to the API will no longer work on May 5, 2021. For more information, including scheduled brownouts, see the blog post.
Now, let’s start filling out our simple server. Create a file called server.rb and paste this into it:
require
'sinatra'
require
'rest-client'
require
'json'
CLIENT_ID = ENV['GH_BASIC_CLIENT_ID'
]CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID'
]get '/'
do
erb :index
, :locals
=> {:client_id
=> CLIENT_ID}end
Your client ID and client secret keys come from your application’s configurationpage. You should never, ever store these values inGitHub–or any other public place, for that matter. We recommend storing them asenvironment variables–which is exactly what we’ve done here.
Next, in views/index.erb, paste this content:
<
html
> <
head
> </
head
> <
body
> <
p
> Well, hello there! </
p
> <
p
> We're going to now talk to the GitHub API. Ready? <
a
href
="https://github.com/login/oauth/authorize?scope=user:email&client_id=<%=
client_id
%>"
>Click here</
a
> to begin! </
p
> <
p
> If that link doesn't work, remember to provide your own <
a
href
="/apps/building-oauth-apps/authorizing-oauth-apps/"
>Client ID</
a
>! </
p
> </
body
></
html
>
(If you’re unfamiliar with how Sinatra works, we recommend reading the Sinatra guide.)
Also, notice that the URL uses the scope
query parameter to define thescopes requested by the application. For our application, we’rerequesting user:email
scope for reading private email addresses.
Navigate your browser to http://127.0.0.1:4567
. After clicking on the link, youshould be taken to GitHub, and presented with a dialog that looks something like this:
If you trust yourself, click Authorize App. Wuh-oh! Sinatra spits out a404
error. What gives?!
Well, remember when we specified a Callback URL to be callback
? We didn’t providea route for it, so GitHub doesn’t know where to drop the user after they authorizethe app. Let’s fix that now!
Providing a callback
In server.rb, add a route to specify what the callback should do:
get '/callback'
do
session_code = request.env['rack.request.query_hash'
]['code'
] result = RestClient.post('https://github.com/login/oauth/access_token'
, {:client_id
=> CLIENT_ID, :client_secret
=> CLIENT_SECRET, :code
=> session_code}, :accept
=> :json
) access_token = JSON.parse(result)['access_token'
]end
After a successful app authentication, GitHub provides a temporary code
value.You’ll need to POST
this code back to GitHub in exchange for an access_token
.To simplify our GET and POST HTTP requests, we’re using the rest-client.Note that you’ll probably never access the API through REST. For a more seriousapplication, you should probably use a library written in the language of your choice.
Checking granted scopes
Users can edit the scopes you requested by directly changing the URL. This can grant your application less access than you originally asked for. Before making any requests with the token, check the scopes that were granted for the token by the user. For more information about requested and granted scopes, see “Scopes for OAuth Apps.”
The scopes that were granted are returned as a part of the response fromexchanging a token.
get '/callback'
do
scopes = JSON.parse(result)['scope'
].split(','
) has_user_email_scope = scopes.include
? 'user:email'
end
In our application, we’re using scopes.include?
to check if we were grantedthe user:email
scope needed for fetching the authenticated user’s privateemail addresses. Had the application asked for other scopes, we would havechecked for those as well.
Also, since there’s a hierarchical relationship between scopes, you shouldcheck that you were granted the lowest level of required scopes. For example,if the application had asked for user
scope, it might have been granted onlyuser:email
scope. In that case, the application wouldn’t have been grantedwhat it asked for, but the granted scopes would have still been sufficient.
Checking for scopes only before making requests is not enough since it’s possiblethat users will change the scopes in between your check and the actual request.In case that happens, API calls you expected to succeed might fail with a 404
or 401
status, or return a different subset of information.
To help you gracefully handle these situations, all API responses for requestsmade with valid tokens also contain an X-OAuth-Scopes
header.This header contains the list of scopes of the token that was used to make therequest. In addition to that, the OAuth Applications API provides an endpoint tocheck a token for validity.Use this information to detect changes in token scopes, and inform your users ofchanges in available application functionality.
Making authenticated requests
At last, with this access token, you’ll be able to make authenticated requests asthe logged in user:
auth_result = JSON.parse(RestClient.get('https://api.github.com/user'
, {:params
=> {:access_token
=> access_token}})) if
has_user_email_scope auth_result['private_emails'
] = JSON.parse(RestClient.get('https://api.github.com/user/emails'
, {:params
=> {:access_token
=> access_token}}))end
erb :basic
, :locals
=> auth_result
We can do whatever we want with our results. In this case, we’ll just dump them straight into basic.erb:
<
p
>Hello, <%= login
%>!
</
p
><
p
> <%
if
!email.nil
? && !email.empty? %> It looks like your public email address is <%=
email
%>. <%
else
%> It looks like you don't have a public email. That's cool. <%
end
%>
</
p
><
p
> <%
if
defined
? private_emails %> With your permission, we were also able to dig up your private email addresses: <%=
private_emails.map{
|private_email_address|
private_email_address["email"
] }.join(', '
) %> <%
else
%> Also, you're a bit secretive about your private email addresses. <%
end
%>
</
p
>
Implementing “persistent” authentication
It’d be a pretty bad model if we required users to log into the app every singletime they needed to access the web page. For example, try navigating directly tohttp://127.0.0.1:4567/basic
. You’ll get an error.
What if we could circumvent the entire”click here” process, and just remember that, as long as the user’s logged intoGitHub, they should be able to access this application? Hold on to your hat,because that’s exactly what we’re going to do.
Our little server above is rather simple. In order to wedge in some intelligentauthentication, we’re going to switch over to using sessions for storing tokens.This will make authentication transparent to the user.
Also, since we’re persisting scopes within the session, we’ll need tohandle cases when the user updates the scopes after we checked them, or revokesthe token. To do that, we’ll use a rescue
block and check that the first APIcall succeeded, which verifies that the token is still valid. After that, we’llcheck the X-OAuth-Scopes
response header to verify that the user hasn’t revokedthe user:email
scope.
Create a file called advanced_server.rb, and paste these lines into it:
require
'sinatra'
require
'rest_client'
require
'json'
CLIENT_ID = ENV['GH_BASIC_CLIENT_ID'
]CLIENT_SECRET = ENV['GH_BASIC_SECRET_ID'
]use Rack::Session::Pool, :cookie_only
=> false
def
authenticated?
session[:access_token
]end
def
authenticate!
erb :index
, :locals
=> {:client_id
=> CLIENT_ID}end
get '/'
do
if
!authenticated? authenticate! else
access_token = session[:access_token
] scopes = [] begin
auth_result = RestClient.get('https://api.github.com/user'
, {:params
=> {:access_token
=> access_token}, :accept
=> :json
}) rescue
=> e session[:access_token
] = nil
return
authenticate! end
if
auth_result.headers.include
? :x_oauth_scopes
scopes = auth_result.headers[:x_oauth_scopes
].split(', '
) end
auth_result = JSON.parse(auth_result) if
scopes.include
? 'user:email'
auth_result['private_emails'
] = JSON.parse(RestClient.get('https://api.github.com/user/emails'
, {:params
=> {:access_token
=> access_token}, :accept
=> :json
})) end
erb :advanced
, :locals
=> auth_result end
end
get '/callback'
do
session_code = request.env['rack.request.query_hash'
]['code'
] result = RestClient.post('https://github.com/login/oauth/access_token'
, {:client_id
=> CLIENT_ID, :client_secret
=> CLIENT_SECRET, :code
=> session_code}, :accept
=> :json
) session[:access_token
] = JSON.parse(result)['access_token'
] redirect '/'
end
Much of the code should look familiar. For example, we’re still using RestClient.get
to call out to the GitHub API, and we’re still passing our results to be renderedin an ERB template (this time, it’s called advanced.erb
).
Also, we now have the authenticated?
method which checks if the user is alreadyauthenticated. If not, the authenticate!
method is called, which performs theOAuth flow and updates the session with the granted token and scopes.
Next, create a file in views called advanced.erb, and paste this markup into it:
<
html
> <
head
> </
head
> <
body
> <
p
>Well, well, well, <%= login
%>!
</
p
> <
p
> <%
if
!email.empty? %> It looks like your public email address is <%=
email
%>. <%
else
%> It looks like you don't have a public email. That's cool. <%
end
%>
</
p
> <
p
> <%
if
defined
? private_emails %> With your permission, we were also able to dig up your private email addresses: <%=
private_emails.map{
|private_email_address|
private_email_address["email"
] }.join(', '
) %> <%
else
%> Also, you're a bit secretive about your private email addresses. <%
end
%>
</
p
> </
body
></
html
>
From the command line, call ruby advanced_server.rb
, which starts up yourserver on port 4567
— the same port we used when we had a simple Sinatra app.When you navigate to http://127.0.0.1:4567
, the app calls authenticate!
which redirects you to /callback
. /callback
then sends us back to /
,and since we’ve been authenticated, renders advanced.erb.
We could completely simplify this roundtrip routing by simply changing our callbackURL in GitHub to /
. But, since both server.rb and advanced.rb are relying onthe same callback URL, we’ve got to do a little bit of wonkiness to make it work.
Also, if we had never authorized this application to access our GitHub data,we would’ve seen the same confirmation dialog from earlier pop-up and warn us.