OAuth 2.0 Demo Application with GitHub API's
What is OAuth 2.0 Authorization Framework?
Today
I will be discussing about OAuth 2.0 Framework and how to implement this in a
web application along with a demonstration.
The
OAuth 2.0 authorization framework enables a third-party application to obtain
limited access to an HTTP service, either on behalf of a resource owner by
orchestrating an approval interaction between the resource owner and the HTTP
service, or by allowing the third-party application to obtain access on its own
behalf.
In
the traditional client-server authentication model, the client requests a
protected resource on the server by authenticating with the server using the
resource owner’s credentials. In order to provide third-party applications
access to protected resources, the recourse owner shares its credentials with
the third party. This would create
several problems and limitations as shown below:
·
Third-party applications are
required to store the resource owner’s credentials for future use in clear
text.
·
Servers are required to support
password authentication, despite the security weaknesses inherent in passwords.
·
Third-party applications gain
access to the resource owner’s protected resources, leaving resource owners
without any ability to restrict duration or access to a limited subset of
resources.
·
Resource owners cannot revoke
access to an individual third party without revoking access to all third
parties.
·
Compromise of any third-party
application results in compromise of the end-user’s password and all of the
data protected by that password.
OAuth
addresses these issues by introducing an authentication layer and separating
the role of the client from the resource owner.
OAuth,
the client requests access to resources controlled by the resource owner and
hosted by the resource server and is issued a set of different credentials than
those of the resource owner. Rather than using the resource owner’s credentials
to access the protected information, the client obtains an access token. An access token is a string with a specific
scope and a specific life time and also, with other access attributes.
These
access tokens are issued to the third-party clients by authorizing the server
with the approval of the resource owner. The client uses the access token to
access the protected resources hosted by the resource server.
What are the different roles in OAuth 2.0?
In OAuth 2.0 Framework they have defined
some roles as follows:
·
Resource owner
o
It is an entity which can grant
the access to a protected resource.
·
Resource server
o
This is the server that is
hosting the protected information, capable of accepting and responding to the
protected requests using access tokens.
·
Client
o
It is an application that makes
protected resource requests on behalf of the resource owner ad with its
authorization.
·
Authorization server
o
The server issuing the tokens
to the client after successfully authenticating the resource owner and
obtaining the authentication.
Authorization Grants and their Types
Authorization Grant is a credential
representing the resource owner’s authorization used by the client to obtain an
access token.
There are four grant types. They are:
·
Authorization Code
·
Implicit
·
Client Credentials
First go to the https://github.com/settings/developers and login to the GitHub or create a new account if you do not have an account. Then you will see a screen like bellow. In order to create a new OAuth application click on ‘New OAuth App’ button. And fill the necessary fields accordingly.
After creating the application, Client id and client secret will be show like bellow.
Once it load in the browse it looks like bellow.
Once click on the ‘login with GitHub’ button application ask to sign with your GitHub account and ask permission for grant access to the application.
How to develop the application
In
order to create an OAuth flow with GitHub, we need to follow simple 4 steps. Those
steps are briefly explain in the above diagram. From this blog we will going to
talk about how these 4 steps fulfil and how to create a simple ‘Repository
details viewing’ app.
[Refer GitHub Repo for more details : https://github.com/KMKasunMadusanka/OAuth_Sample_App ]
[Refer GitHub Repo for more details : https://github.com/KMKasunMadusanka/OAuth_Sample_App ]
In
order to create this simple Repo viewing application, I have used Angular
6 for front-end development and NodeJs for backend development. Let’s
see how to implement this application now.
First go to the https://github.com/settings/developers and login to the GitHub or create a new account if you do not have an account. Then you will see a screen like bellow. In order to create a new OAuth application click on ‘New OAuth App’ button. And fill the necessary fields accordingly.
Note:
- Give valid URL for call back url, because the code which is generated from
the GitHub will be send to that URL as a query parameter.
After creating the application, Client id and client secret will be show like bellow.
2.
Generate
access code.
In order to obtain access code, we need to
make a GET request to the following URL with the bellow parameters.
GET
https://github.com/login/oauth/authorize
Parameters
| Name | Type | Description |
|---|---|---|
client_id | string | Required. The client ID you received from GitHub when you registered. |
redirect_uri | string | The URL in your application where users will be sent after authorization. See details below about redirect urls. |
scope | string | A space-delimited list of scopes. If not provided, scope defaults to an empty list for users that have not authorized any scopes for the application. For users who have authorized scopes for the application, the user won't be shown the OAuth authorization page with the list of scopes. Instead, this step of the flow will automatically complete with the set of scopes the user has authorized for the application. For example, if a user has already performed the web flow twice and has authorized one token with user scope and another token with repo scope, a third web flow that does not provide a scope will receive a token with user and repo scope. |
state | string | An unguessable random string. It is used to protect against cross-site request forgery attacks. |
allow_signup | string | Whether or not unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. The default is true. Use false in the case that a policy prohibits signups. |
In
our application we have make this GET request in the login page. For that I have
used a simple anchor tag with href attribute.
[Refer Repo: - Angular-Front-end/src/app/components/login/login.component.html]
<div class="main-content">
<div class="title">
Repo Detetails Viewer
</div>
<div class="body">
<a href="https://github.com/login/oauth/authorize?client_id=50f6f7c85489adbadbb9&redirect_uri=http://localhost:4200/mainPage&scope=user&state=123456&allow_signup=false"
class="btn btn-dark btn-md" role="button">
</a>
</div>
</div>
Once it load in the browse it looks like bellow.
Once click on the ‘login with GitHub’ button application ask to sign with your GitHub account and ask permission for grant access to the application.
After
confirm the authorization, page will automatically redirect to the call back
URL (In my case it is: - http://localhost:4200/mainPage
). Within that URL, access token will be shown visible like bellow.
3.
Obtain
Access Token
When
this page loaded, I have retrieve the code from the query parameter of the URL
and send to the backend POST endpoint (http://localhost:5000/accessToken )
with ‘code’ as a parameter.
Then,
within that endpoint it calls to the access token generated POST API.
POST https://github.com/login/oauth/access_token
Parameters
| Name | Type | Description |
|---|---|---|
client_id | string | Required. The client ID you received from GitHub for your GitHub App. |
client_secret | string | Required. The client secret you received from GitHub for your GitHub App. |
code | string | Required. The code you received as a response to Step 1. |
redirect_uri | string | The URL in your application where users are sent after authorization. |
state | string | The unguessable random string you provided in Step 1. |
Coding
implementation is like bellow.
Front
End: -
[Reference Path: - Angular-front-end/ src/app/services/ git-hub-service.service.ts]
genrateAccessToken(code:String) {
return this.http.post(this.baseUrl+"/accessToken", {"code":code});
}
Back
End:-
[Reference Path: - Node-Back-End/server.js]
app.post('/accessToken', (req, res, next) => {
axios.post('https://github.com/login/oauth/access_token', {
"client_id": "XXXXXXXXXXXX",
"client_secret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"code": req.body.code,
"redirect_uri": "http://localhost:4200/mainPage",
"state": "123456"
})
.then(function (response) {
console.log(response.data.split('&')[0].split('=')[1]);
res.send({ "access_token": response.data.split('&')[0].split('=')[1] })
})
.catch(function (error) {
console.log(error);
});
})
4.
Access
the GitHub API’s with Access token.
Once
access token is generated. We can call to the GET request and get the particular
user details as bellow.
GET https://api.github.com/user?access_token=...
Output:-
{
"login":"KMKasunMadusanka",
"id":25845466,
"node_id":"MDQ6VXNlcjI1ODQ1NDY2",
"avatar_url":"https://avatars3.githubusercontent.com/u/25845466?v=4",
"gravatar_id":"",
"url":"https://api.github.com/users/KMKasunMadusanka",
"html_url":"https://github.com/KMKasunMadusanka",
"followers_url":"https://api.github.com/users/KMKasunMadusanka/followers",
"following_url":"https://api.github.com/users/KMKasunMadusanka/following{/other_user}",
"gists_url":"https://api.github.com/users/KMKasunMadusanka/gists{/gist_id}",
"starred_url":"https://api.github.com/users/KMKasunMadusanka/starred{/owner}{/repo}",
"subscriptions_url":"https://api.github.com/users/KMKasunMadusanka/subscriptions",
"organizations_url":"https://api.github.com/users/KMKasunMadusanka/orgs",
"repos_url":"https://api.github.com/users/KMKasunMadusanka/repos",
"events_url":"https://api.github.com/users/KMKasunMadusanka/events{/privacy}",
"received_events_url":"https://api.github.com/users/KMKasunMadusanka/received_events",
"type":"User",
"site_admin":false,
"name":"Kasun Madusanka",
"company":null,
"blog":"",
"location":null,
"email":null,
"hireable":null,
"bio":null,
"public_repos":20,
"public_gists":0,
"followers":3,
"following":8,
"created_at":"2017-02-17T13:25:43Z",
"updated_at":"2018-10-14T06:49:30Z",
"private_gists":0,
"total_private_repos":0,
"owned_private_repos":0,
"disk_usage":100065,
"collaborators":0,
"two_factor_authentication":false,
"plan":{
"name":"free",
"space":976562499,
"collaborators":0,
"private_repos":0
}
}
Using
these data we can show the Repo details details as bellow.








Comments
Post a Comment