Wednesday 14 June 2017

ASP.Net Web forms: Implementing google and facebook login

In this tutorial I am going to implement login with google and facebook accounts functionality. 

Step 1: Setup the app on facebook account. Login to your facebook account and follow the following screens to setup the developer app into your facebook account.
 












Step 2: Now time to Setup the google developer app to enable the google login in our website. Login to your google account and follow the following link to enable google login:

https://developers.google.com/identity/sign-in/web/devconsole-project

Step 3: After setup the google and facebook developer apps setup the appId and appSecret info in web.config file as following:
  <appSettings>
    <!--Google Settings-->
    <add key="google_client_id" value="726998862019-7n0taqcjkltcr5j2n5bdkfmtlggasn9c.apps.googleusercontent.com"/>
    <add key="google_client_secret" value="pm7r5KLiiDpYuuiva8r3td9R"/>
    <add key="google_redirect_url" value="http://localhost:65399/default.aspx"/>
    <add key="Googleurl" value="https://accounts.google.com/o/oauth2/auth?response_type=code&amp;redirect_uri={0}&amp;scope=https://www.googleapis.com/auth/userinfo.email%20https://www.googleapis.com/auth/userinfo.profile&amp;client_id={1}"/>
    <add key="googleoAuthUrl" value="https://accounts.google.com/o/oauth2/token"/>
    <add key="googleoAccessUrl" value="https://www.googleapis.com/oauth2/v1/userinfo?access_token="/>

    <!--Facebook Settings-->
    <add key="Facebook_AppId" value="1935041566739719"/>
    <add key="Facebook_AppSecret" value="4dd0e4c0c76e9d93f34da28409c4cd51"/>
    <add key="Facebook_RedirectUrl" value="http://localhost:65399/default.aspx"/>
    <add key="Facebook_scope" value="email, publish_actions, public_profile"/>
    <add key="Facebook_url" value="https://graph.facebook.com/oauth/authorize?client_id={0}&amp;redirect_uri={1}&amp;scope={2}"/>
    <add key="FacebookOAuthurl" value="https://graph.facebook.com/oauth/access_token?client_id={0}&amp;redirect_uri={1}&amp;scope={2}&amp;code={3}&amp;client_secret={4}"/>
    <add key="FacebookAccessUrl" value="https://graph.facebook.com/me?fields=first_name,last_name,gender,locale,link,email&amp;access_token="/>
  </appSettings>

Step 4: Add the following html code in your .aspx page.
    <div class="row form-group" style="margin-top: 40px;">
        <div class="col-md-12">
            <asp:Button CssClass="btn btn-default" ID="GoogleBtn" runat="server" Text="Login with Google account"

OnClick="GoogleBtnClick"></asp:Button>
            <asp:Button CssClass="btn btn-default" ID="FacebookBtn" runat="server" Text="Login with Facebook account"

OnClick="FacebookBtnClick"></asp:Button>
        </div>
    </div>
    <div class="row form-group">
        <h3 class="col-md-12">
            User Info:
        </h3>
        <div class="col-md-12">
            <asp:Literal ID="txtResponse" runat="server">External user info will populate here in json format.</asp:Literal>
        </div>
    </div>

Step 5: Add following model classes in your project:
public class GoogleToken
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
    public string id_token { get; set; }
    public string refresh_token { get; set; }
}
public class GoogleInfo
{
    public string id { get; set; }
    public string email { get; set; }
    public bool verified_email { get; set; }
    public string name { get; set; }
    public string given_name { get; set; }
    public string family_name { get; set; }
    public string picture { get; set; }
    public string locale { get; set; }
    public string gender { get; set; }
}
public class FacebookInfo
{
    public string first_name { get; set; }
    public string last_name { get; set; }
    public string gender { get; set; }
    public string locale { get; set; }
    public string link { get; set; }
    public string id { get; set; }
    public string email { get; set; }
}

public class FacebookToken
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
}



Step 6: Add the following c# code in your .aspx.cs page.
protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["LoginWith"] != null)
            {
                switch (Session["LoginWith"].ToString())
                {
                    case "google":
                        FetchUserSocialDetail("google");
                        break;
                    case "facebook":
                        FetchUserSocialDetail("facebook");
                        break;
                }
            }
        }

        protected void GoogleBtnClick(object sender, EventArgs e)
        {
            GetSocialCredentials("google");
        }
        protected void FacebookBtnClick(object sender, EventArgs e)
        {
            GetSocialCredentials("facebook");
        }
        private void GetSocialCredentials(String provider)
        {
            if (provider == "google")
            {
                string Googleurl = String.Format(ConfigurationManager.AppSettings["Googleurl"], ConfigurationManager.AppSettings

["google_redirect_url"], ConfigurationManager.AppSettings["google_client_id"]);
                Session["LoginWith"] = provider;
                Response.Redirect(Googleurl);
            }
            else if (provider == "facebook")
            {
                string Facebookurl = string.Format(ConfigurationManager.AppSettings["Facebook_url"], ConfigurationManager.AppSettings

["Facebook_AppId"], ConfigurationManager.AppSettings["Facebook_RedirectUrl"], ConfigurationManager.AppSettings["Facebook_scope"]);
                Session["LoginWith"] = provider;
                Response.Redirect(Facebookurl);
            }
        }

        private void FetchUserSocialDetail(String provider)
        {
            try
            {
                if (provider == "google")
                {
                    var url = Request.Url.Query;
                    if (!string.IsNullOrEmpty(url))
                    {
                        string queryString = url.ToString();
                        string[] words = queryString.Split('=');
                        string code = words[1];
                        if (!string.IsNullOrEmpty(code))
                        {
                            //string Parameters =  "code=" + code + "&client_id=" + ConfigurationManager.AppSettings["google_client_id"] +

"&client_secret=" + ConfigurationManager.AppSettings["google_client_secret"] + "&redirect_uri=" + ConfigurationManager.AppSettings

["google_redirect_url"] + "&grant_type=authorization_code";
                            string parameters = string.Format("code={0}&client_id={1}&client_secret={2}&redirect_uri={3}

&grant_type=authorization_code",
                                code,
                                ConfigurationManager.AppSettings["google_client_id"],
                                ConfigurationManager.AppSettings["google_client_secret"],
                                ConfigurationManager.AppSettings["google_redirect_url"]);
                            string response = MakeWebRequest(ConfigurationManager.AppSettings["googleoAuthUrl"], "POST", "application/x-www-

form-urlencoded", parameters);
                            GoogleToken tokenInfo = new JavaScriptSerializer().Deserialize<GoogleToken>(response);

                            if (tokenInfo != null)
                            {
                                if (!string.IsNullOrEmpty(tokenInfo.access_token))
                                {
                                    var googleInfo = MakeWebRequest(ConfigurationManager.AppSettings["googleoAccessUrl"] +

tokenInfo.access_token, "GET");
                                    GoogleInfo profile = new JavaScriptSerializer().Deserialize<GoogleInfo>(googleInfo);
                                    txtResponse.Text = googleInfo;
                                }
                            }
                        }
                    }
                    Session.Remove("LoginWith");
                }
                else if (provider == "facebook")
                {
                    if (Request["code"] != null)
                    {
                        string url = string.Format(ConfigurationManager.AppSettings["FacebookOAuthurl"],
                            ConfigurationManager.AppSettings["Facebook_AppId"],
                            ConfigurationManager.AppSettings["Facebook_RedirectUrl"],
                            ConfigurationManager.AppSettings["Facebook_scope"],
                            Request["code"].ToString(),
                            ConfigurationManager.AppSettings["Facebook_AppSecret"]);

                        string tokenResponse = MakeWebRequest(url, "GET");
                        var tokenInfo = new JavaScriptSerializer().Deserialize<FacebookToken>(tokenResponse);
                        var facebookInfoJson = MakeWebRequest(ConfigurationManager.AppSettings["FacebookAccessUrl"] + tokenInfo.access_token,

"GET");
                        FacebookInfo objUser = new JavaScriptSerializer().Deserialize<FacebookInfo>(facebookInfoJson);
                        txtResponse.Text = facebookInfoJson;
                    }
                }
                Session.Remove("LoginWith");
            }
            catch (Exception ex)
            {
                Response.Redirect("error.aspx");
            }
        }

        /// <summary>
        /// Calling 3rd party web apis.
        /// </summary>
        /// <param name="destinationUrl"></param>
        /// <param name="methodName"></param>
        /// <param name="requestJSON"></param>
        /// <returns></returns>
        public string MakeWebRequest(string destinationUrl, string methodName, string contentType = "", string requestJSON = "")
        {
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(destinationUrl);
                request.Method = methodName;
                if (methodName == "POST")
                {
                    byte[] bytes = System.Text.Encoding.ASCII.GetBytes(requestJSON);
                    request.ContentType = contentType;
                    request.ContentLength = bytes.Length;
                    using (Stream requestStream = request.GetRequestStream())
                    {
                        requestStream.Write(bytes, 0, bytes.Length);
                    }
                }
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                        {
                            return reader.ReadToEnd();
                        }
                    }
                }

                return null;
            }
            catch (WebException webEx)
            {
                return webEx.Message;
            }
        }

Download the complete sample code here

13 comments:

  1. Worked so well thank you so much.

    However the url parameters returned seem to have a different format

    Instead of this:
    string queryString = url.ToString(); string[] words = queryString.Split('='); string code = words[1];

    Easier and proper:
    string code = Request.QueryString["code"];

    Thanks again you are savior.

    ReplyDelete
    Replies
    1. Thank you for correcting me. Your comment will help other people if they stuck. Thank you so much :).

      Delete
  2. Just wanted to say a big thanks, the only straightforward and still useful resource for web forms actually on the web for sso with google and facebook.
    thanks!

    ReplyDelete
  3. Thank you very much for this code

    ReplyDelete
  4. Hello, im getting bad request error on google login, any help?

    ReplyDelete
    Replies
    1. At which request you getting bad request?

      Delete
  5. I get errors, even when I use your project. Facebook error is that the URL can't be loaded because the domain of this URL is not added to the domains of this app. But I definitely did do this.

    Google shows the login screen where I can click my google account, so that is good but after I click my google account it redirects me to a website that can't be reached.

    ReplyDelete
    Replies
    1. Well, Google I got actually working, it was because I was using SSL.

      Facebook remains to do the same error.

      Delete
  6. Hello, thanks so much for sharing. I just have one problem. I am getting error on the following line for facebook, but it works fine for google. Any idea?


    Error
    "The remote server returned an error: (400) Bad Request."

    Detail:
    at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializePrimitiveObject()
    at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
    at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
    at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
    at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)

    ReplyDelete
  7. Dear sir,
    i have stuck in facebook integration in my app, i am able to get response but AccessUrl webmethod getting an error like 400 kindly help on the same
    "The remote server returned an error: (400) Bad Request."

    ReplyDelete
    Replies
    1. Looks like you are not sending correct input parameters. Can you please share request details like url and input request body so that I can check.

      Delete