Introduction
 
 Nowadays, security is a major concern for every service provider like Google,  Yahoo, Microsoft etc. and that’s why each service provider who is providing  some external service to another app is following the protocol defined by OAuth.
 
 I am going to describe here how to implement Google OAuth in an ASP.NET app.
 
 Prerequisites
 
 You should have a basic knowledge of,
  Steps for implementing
 
 For implementing OAuth, we will have to follow this series of steps.
  	- Create a project on Google Console.
- Get the client id and client secret from the project.
- Writing the code for authorizing the user by Google.
- Writing code for exchanging the authorization code for refresh token.
- Writing code for exchanging refresh token for access token.
Don’t worry about the above steps. I am going to explain these in detail, along with a proper demo.
 
 Let’s Start.
  	- Create a project on Google Console
 
 Go to the website of Google Console and click on Project -> New  	Project.
 
 ![Google]() 
 
 After that, a dialog box will appear. Write your project name and click on  	Create.
 
 ![Google]() 
 
 You have successfully created a project.
 
 
- Getting client id and client secret
 
 Follow the steps shown in the screenshot.
 
  		- Click on Credentials
 
 ![Google]() 
 
 
- Click on down arrow button near the Create Credentials button. Clicking the down arrow button will open a dropdown box . There, click on OAuth Client ID.
 
 ![Google]() 
 
 
- Click on "Configure Consent" screen.
 
 ![Google]() 
 
 
- Fill all the details and click on Save.
 
 ![Google]() 
 
 
- Again, you will be redirected to the credentials screen. Click on Web  		Application and name your web app. Then, click on "Create" button. For the time being, ignore the other text boxes which I will explain later in this  		article.
 
 ![Google]() 
 
 
- You will get your client id and client secret in a pop up. Copy the  		client id and client secret and keep it somewhere safe (Don't worry if  		you lose this code, you can get this code later from developer console,But if someone will get these data they can misuse this).
 
 
 
- Writing code for authorizing the user by Google
 
  		- Let’s create an ASP.NET project.
 
 ![Google]() 
 
 I am creating a web form project, but you can create any project, like ASP.NET MVC or any other.
 
 
-  Add a web form inside the project with name – GoogleCallBack.  		This will be used as redirect URL. Don’t worry ! You will understand it  		later.
 
 ![Google]() 
 
 ![Google]() 
 
 
- Add a web form inside the project with name - "Authorize" and paste the  		following HTML code inside the form.
 - <form id="form1" runat="server" method="get">  
-     <div> Enter User Id: <input type="text" name="UserId"> </div>  
-     <p> <button type="submit">Submit</button> </p>  
- </form>  
 
 
 
- Put the client id and client secret in web.config under “appSettings”,  		so that you can change this value later and it can be globally available  		for any page.
 
 ![Google]() 
 
 
- Remember, we have left some setup of project on Google Developer  		Console. It's time to complete them, otherwise Google will decline the  		authorization. So, perform the following steps in serial order. 			 				- Run the project.
 
 ![Google]() 
 
 
- Open the Google developer console.
 
- Go to Credentials.
 
- Click on "Edit OAuth client".
 
 ![Google]() 
 
 
- Now, copy the project URL and paste in textbox of authorized  				JavaScript origin. Keep it open.
 
- Open the googlecallback.aspx in browser and copy the URL.
 
- Paste the url in authorized redirect uri.
 
 ![Google]() 
 
 Now, we have completed the settings of the project on Google developer  				console. It's time to get back to our implementation part.
 
 
 
- Create a database with any name and inside the database - create the  		table having the below design or you can also paste the below code in order  		to create the table.
 - create table Member(UserId int primary key, RefreshToken varchar(200), GmailId varchar(200))  
 
![Google]() 
 
 
- Add connection string in web.config .Sorry, I am not going to describe this.I assume you know how to do this one.
 
- It is time to write the code for authorizing user.
 
 For Authorizing the user by Google, you will have to redirect the user  		to Google Authorizing URL with the following query string
 
  			- client_id 
 You will have to pass the client id that you got  			from Google console by creating a project.
 
 
-  redirect_uri
 You will have to pass an absolute url.  			Google will redirect the user to this url after authorization with  			some value as ‘code’ or ‘error’ if any error occurred.
 
 
- access_type
 This will be used by Google to know what type of  			access you want. There are two values – ‘online’ or ‘offline’. Default  			value is ‘online’, but we set it as ‘offline’ because we want the  			user to authenticate one time and use the service again and again.
 
 
-  state
 You can set any value.The same value will be  			returned by Google after authorization. This is used to know the  			user details or any other things. You will understand this later.
 
 
- login_hint
 This value will be automatically filled by Google in  			email text box.
 
 
- scope 
 This value will be used by Google to know what type of  			service an app is requesting for the user. e.g – Gmail, Calendar,  			Google or user info etc. You can pass multiple values separated by  			space.
 
 So, let's write the code for authorizing user. 
 
 Copy the below code in authorize.aspx.cs under partial class -
 
 - protected void Page_Load(object sender, EventArgs e) {  
-           
-         string UserId = Request.QueryString["UserId"];  
-         if (UserId != null)   
-         {  
-             if (IsAuthorized(UserId))   
-             {  
-                 string EmailId = GetGmailId(UserId);   
-                   
-                 ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "alert('" + EmailId + "')", true);  
-             } else {  
-                 AuthorizeUser(UserId);   
-             }  
-         }  
-     }  
-       
-       
-       
-       
-       
- private string GetGmailId(string userId) {  
-     SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);  
-     string Query = "select GmailId from Member where UserId=" + userId;  
-     SqlCommand Cmd = new SqlCommand(Query, Con);  
-     Con.Open();  
-     string Result = Cmd.ExecuteScalar().ToString();  
-     Con.Close();  
-     return Result;  
- }  
- private bool IsAuthorized(string userId) {  
-     SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);  
-     string Query = "select count(*) from Member where UserId=" + userId;  
-     SqlCommand Cmd = new SqlCommand(Query, Con);  
-     Con.Open();  
-     int Result = (int) Cmd.ExecuteScalar();  
-     Con.Close();  
-     return Result > 0 ? true : false;  
- }  
- private void AuthorizeUser(string data) {  
-         string Url = GetAuthorizationUrl(data);  
-         HttpContext.Current.Response.Redirect(Url, false);  
-     }  
-       
-       
-       
-       
-       
- private string GetAuthorizationUrl(string data) {  
-     string ClientId = ConfigurationManager.AppSettings["ClientId"];  
-     string Scopes = "https://www.googleapis.com/auth/userinfo.email";  
-       
-     string RedirectUrl = "http://localhost:52403/GoogleCallBack.aspx";  
-     string Url = "https://accounts.google.com/o/oauth2/auth?";  
-     StringBuilder UrlBuilder = new StringBuilder(Url);  
-     UrlBuilder.Append("client_id=" + ClientId);  
-     UrlBuilder.Append("&redirect_uri=" + RedirectUrl);  
-     UrlBuilder.Append("&response_type=" + "code");  
-     UrlBuilder.Append("&scope=" + Scopes);  
-     UrlBuilder.Append("&access_type=" + "offline");  
-     UrlBuilder.Append("&state=" + data);   
-     return UrlBuilder.ToString();  
- }  
 
  		- When the page loads, it will retrieve the user id from query  		string.
- If we have found the user id from query string, it will check whether  		user is already authorized or not.
- If the user is already authorized, then we will fetch the email from  		database and show it to the user.
- If the user is not authorized, we will authorize the user by following the below steps. 
 
  			- We will create an authorization url - this includes creating  			query string with client id, scope, and all other things that I mentioned earlier.
- We will redirect the user to the created url.
 
 Now, we have web page which will authorize the user. Let’s create the page  	for Saving the data in database after successful authorization. So we will  	have to write code in GoogleCallBack.aspx.cs
 
 
- Writing code for exchanging the authorization code
 
 After successful authorization, Google will call this page with an  	authorization code which is temporary – that means it will expire after few  	hour. probably an hour. But we want the user to authenticate one time and  	use the service again and again.So what to do?
 
 By using authorization code, we can get a refresh token which is valid for a   lifetime but it is not used for getting any service. So again the question  	will be, then what is the meaning of refresh token?
 
 By using refresh token, we can get access token which is used for getting  	service and again access token is temporary. So every time you want to use  	any service, you will have to get access token.
 
 I think now you understand the whole flow.So basically we will have to  	perform the following steps.
 
  		- Get the authorization code.
-  Exchange the authorization code for refresh token.
-  save the refresh token in database.
-  Exchange refresh token for access token.
- Use access token for getting any service.
 So, let’s write the code.
 
 Copy the below code in GoogleCallBack.aspx.cs under namespace.
 
 - public partial class GoogleCallBack: System.Web.UI.Page {  
-     protected void Page_Load(object sender, EventArgs e) {  
-           
-         string Error = Request.QueryString["error"];  
-           
-         string Code = Request.QueryString["code"];  
-         if (Error != null) {} else if (Code != null) {  
-               
-             string UserId = Request.QueryString["state"];  
-               
-             int Id = Convert.ToInt32(UserId);  
-             string AccessToken = string.Empty;  
-             string RefreshToken = ExchangeAuthorizationCode(Id, Code, out AccessToken);  
-               
-             SaveRefreshToken(Id, RefreshToken);  
-               
-             string EmailId = FetchEmailId(AccessToken);  
-               
-             SaveEmailId(UserId, EmailId);  
-               
-             string Url = "Authorize.aspx?UserId=" + UserId;  
-             Response.Redirect(Url, true);  
-         }  
-     }  
-     private string ExchangeAuthorizationCode(int userId, string code, out string accessToken) {  
-         accessToken = string.Empty;  
-         string ClientSecret = ConfigurationManager.AppSettings["ClientSecret"];  
-         string ClientId = ConfigurationManager.AppSettings["ClientId"];  
-           
-         string RedirectUrl = "http://localhost:52403/GoogleCallBack.aspx";  
-         var Content = "code=" + code + "&client_id=" + ClientId + "&client_secret=" + ClientSecret + "&redirect_uri=" + RedirectUrl + "&grant_type=authorization_code";  
-         var request = WebRequest.Create("https://accounts.google.com/o/oauth2/token");  
-         request.Method = "POST";  
-         byte[] byteArray = Encoding.UTF8.GetBytes(Content);  
-         request.ContentType = "application/x-www-form-urlencoded";  
-         request.ContentLength = byteArray.Length;  
-         using(Stream dataStream = request.GetRequestStream()) {  
-             dataStream.Write(byteArray, 0, byteArray.Length);  
-             dataStream.Close();  
-         }  
-         var Response = (HttpWebResponse) request.GetResponse();  
-         Stream responseDataStream = Response.GetResponseStream();  
-         StreamReader reader = new StreamReader(responseDataStream);  
-         string ResponseData = reader.ReadToEnd();  
-         reader.Close();  
-         responseDataStream.Close();  
-         Response.Close();  
-         if (Response.StatusCode == HttpStatusCode.OK) {  
-             var ReturnedToken = JsonConvert.DeserializeObject < Token > (ResponseData);  
-             if (ReturnedToken.refresh_token != null) {  
-                 accessToken = ReturnedToken.access_token;  
-                 return ReturnedToken.refresh_token;  
-             } else {  
-                 return null;  
-             }  
-         } else {  
-             return string.Empty;  
-         }  
-     }  
-     private void SaveRefreshToken(int userId, string refreshToken) {  
-         SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);  
-         string Query = "insert into Member (UserId,RefreshToken) values(" + userId + ",'" + refreshToken + "')";  
-         SqlCommand Cmd = new SqlCommand(Query, Con);  
-         Con.Open();  
-         int Result = Cmd.ExecuteNonQuery();  
-         Con.Close();  
-     }  
-     private string FetchEmailId(string accessToken) {  
-         var EmailRequest = "https://www.googleapis.com/userinfo/email?alt=json&access_token=" + accessToken;  
-           
-         var Request = WebRequest.Create(EmailRequest);  
-           
-         var Response = (HttpWebResponse) Request.GetResponse();  
-           
-         var DataStream = Response.GetResponseStream();  
-           
-         var Reader = new StreamReader(DataStream);  
-           
-         var JsonString = Reader.ReadToEnd();  
-           
-         Reader.Close();  
-         DataStream.Close();  
-         Response.Close();  
-         dynamic json = JValue.Parse(JsonString);  
-         return json.data.email;  
-     }  
-     private bool SaveEmailId(string userId, string emailId) {  
-         SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);  
-         string Query = "update Member set GmailId='" + emailId + "'where UserId='" + userId + "'";  
-         SqlCommand Cmd = new SqlCommand(Query, Con);  
-         Con.Open();  
-         int Result = Cmd.ExecuteNonQuery();  
-         Con.Close();  
-         return Result > 0 ? true : false;  
-     }  
- }  
- public class Token {  
-     public string access_token {  
-         get;  
-         set;  
-     }  
-     public string token_type {  
-         get;  
-         set;  
-     }  
-     public string expires_in {  
-         get;  
-         set;  
-     }  
-     public string refresh_token {  
-         get;  
-         set;  
-     }  
- }  
 
  		- We have two things that will be returned by google either error or  		code, so we will check first if error is not null. If error is null, that  		means some error has occurred while authorizing.
 
- If error is null then we will check for code and if code is not null  		that means we have a token and user is authorized successfully.
 
- Now, we have got the temporary token, so we will have to use it to  		get the refresh token. We will call the exchange "authorizationcode"  		which will exchange the authorization code and will return refreshtoken  		and access token.(At the time of exchanging authorization code, the  		google also return access token, so we should use this access token  		instead of another http call to get the access token.)
 
- Save the refresh token in database.
 
- Get the email id using access token.
 
- Save the email id in database.
 
-  Redirect the user to authorize.aspx with query string user id  		and now the user is authorized so we will get an alert with the user  		gmail id. Now, we have completed the coding part successfully.It’s time to rock.
 Testing Implementation
 
 Perform the following steps.
 
  		- Run the project.
- Navigate to Authorize.aspx.
- Enter any user id which should be a number .
 
 ![Google]() 
 
 
- Click on Submit If the user will be present inside the db then you  		will get the email id of the user in alert box, otherwise the user will  		be redirected to google authorization site.
 
- An allow screen will appear, where user can see what type of  		access, he/she is giving to the app. Click on Allow button. After  		clicking on Allow button, the refresh token and Gmail id will be saved  		to your DB and the user will be redirected to the authorize page.
 
 ![Google]() 
 
 Cool, Isn’t It?
 
 Now, we have refresh token so the next question will be how to use the  	refresh token to get the access token?
 
 
-  Writing code for exchanging refresh token
 
 Let’s create a web form with name GetEmail. It will be the same like  	Authorize.aspx but instead of getting the email from database, we will fetch  	the email from Google using access token. So, copy the html code from  	Authorize.aspx.
 
 Now, inside the GetEmail.aspx.cs copy the below code under partial class.
 - protected void Page_Load(object sender, EventArgs e) {  
-     string UserId = Request.QueryString["UserId"];  
-     if (UserId != null) {  
-         string RefreshToken = string.Empty;  
-         if (IsAuthorized(UserId, out RefreshToken)) {  
-               
-             string AccessToken = GetAccessToken(RefreshToken);  
-               
-             string EmailId = GetGmailId(AccessToken);  
-             ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "alert('" + EmailId + "')", true);  
-         } else {  
-             string ErrorMsg = "You are not authorized";  
-             ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "alert('" + ErrorMsg + "')", true);  
-         }  
-     }  
- }  
- private bool IsAuthorized(string userId, out string refreshToken) {  
-     SqlConnection Con = new SqlConnection(ConfigurationManager.ConnectionStrings["DbConnection"].ConnectionString);  
-     string Query = "select RefreshToken from Member where UserId=" + userId;  
-     SqlCommand Cmd = new SqlCommand(Query, Con);  
-     Con.Open();  
-     var Result = Cmd.ExecuteScalar();  
-     Con.Close();  
-     refreshToken = Result != null ? Result.ToString() : string.Empty;  
-     return refreshToken.Length > 0 ? true : false;  
- }  
- private string GetGmailId(string accessToken) {  
-     if (accessToken.Length > 0) {  
-         string GmailId = FetchUsersEmail(accessToken);  
-         return GmailId;  
-     } else {  
-         return string.Empty;  
-     }  
- }  
- private string GetAccessToken(string refreshToken) {  
-     string ClientSecret = ConfigurationManager.AppSettings["ClientSecret"];  
-     string ClientId = ConfigurationManager.AppSettings["ClientId"];  
-     var Content = "refresh_token=" + refreshToken + "&client_id=" + ClientId + "&client_secret=" + ClientSecret + "&grant_type=refresh_token";  
-     WebRequest request = WebRequest.Create("https://accounts.google.com/o/oauth2/token");  
-     request.Method = "POST";  
-     byte[] byteArray = Encoding.UTF8.GetBytes(Content);  
-     request.ContentType = "application/x-www-form-urlencoded";  
-     request.ContentLength = byteArray.Length;  
-     using(Stream dataStream = request.GetRequestStream()) {  
-         dataStream.Write(byteArray, 0, byteArray.Length);  
-         dataStream.Close();  
-     }  
-     var Response = (HttpWebResponse) request.GetResponse();  
-     Stream responseDataStream = Response.GetResponseStream();  
-     StreamReader reader = new StreamReader(responseDataStream);  
-     string ResponseData = reader.ReadToEnd();  
-     reader.Close();  
-     responseDataStream.Close();  
-     Response.Close();  
-     if (Response.StatusCode == HttpStatusCode.OK) {  
-         var ReturnedToken = JsonConvert.DeserializeObject < Token > (ResponseData);  
-         return ReturnedToken.access_token;  
-     } else {  
-         return string.Empty;  
-     }  
- }  
- private string FetchUsersEmail(string accessToken) {  
-     var EmailRequest = @ "https://www.googleapis.com/userinfo/email?alt=json&access_token=" + accessToken;  
-       
-     var Request = WebRequest.Create(EmailRequest);  
-       
-     var Response = (HttpWebResponse) Request.GetResponse();  
-       
-     var DataStream = Response.GetResponseStream();  
-       
-     var Reader = new StreamReader(DataStream);  
-       
-     var JsonString = Reader.ReadToEnd();  
-       
-     Reader.Close();  
-     DataStream.Close();  
-     Response.Close();  
-     dynamic json = JValue.Parse(JsonString);  
-     return json.data.email;  
- }  
 
 
  		- We will first check whether user is authorized or not. If authorized    the "IsAuthorized" function will return RefreshToken as out parameter.
 
- We will use that refresh token to get the access token.
 
- After that by using access token, we will get the email id.
 Now, run the project and navigate to GetEmail.aspx. Enter the user id  	and see the page in action.
 
 ![Google]() 
 
 Finally, We have successfully implemented the OAth2.0 authorization for  	Google.
 
 Interesting Points
 
 Have you noticed, we are getting only email id. So, what is the thing which  	is saying to Google that the system wants only email id - the scope is the  	thing that we send at the time of authorization to Google to let Google know  	that the requesting system wants this type of service. You can also send multiple scopes to get the multiple service e.g - Google contacts, Google  	calendar etc.
 
 Want to know how we can get the Google Calendar, Google Contacts or how we  	can upload the file on GoogleDrive?  Let's wait for my next article.
 
References
  	- https://developers.google.com/identity/protocols/OAuth2WebServer