Home ยป How To Guides | Technology

Integrate Google friend connect (GFC) with existing asp.net membership and website

  14. Mar 2010 by Soan

Planning to open your website's membership to people who does not want create another set of user name and password specific to your site?

The answer is Google friend connect (GFC) and openID. GFC lets visitors on your site to be a member of your site with their existing OpenID, Google, Yahoo, Twitter and many other providers.

The benefit is that user a can log in and start interacting with your site using their existing username Password and you get more users to join your site.


Design considerations and assumptions:

  1. You already have implemented asp.net membership in your site and want to integrate GFC with existing asp.net memebership schema.
  2. When the user logs in through GFC, the GFC returns a unique string to identify the user to your site. Now the most important point to consider here is how to create this user in your asp.net membership schema using the server side code (also called code-behind in C#) so that your code can allow the user to log in normally as any other registered user of your site.
    The solution to this is to create a new user in your site with the unique string provided by the GFC. This is just one time activity i.e. the first time GFC user logs-in to your site. You need to just create the new user with the unique GFC id as the username in asp.net schema.

Another point to consider is that the UserName field will contain the GFC unique identifier something like (00847694007627126086). This UserName is not very friendly and hence we need to think of some logic to store the actual user Name (display name) of the user. There is a simple workaround available to cater this situation. This is to say that there can be multiple other solutions to deal with it, but we found the following workaround to be the simplest and best for our situation:


Workaround:

Create the Membership User and then set the user's "comment" field to their Nickname/DisplayName in asp_membership table. This is because the "Hello, Username. Welcome back to the site." message at the top of the page would normally display the user's "username". In the case of GFC users their username would be their GFC string like 00847694007627126086. By storing the Nickname/display name into the comments field we can first check to see if it has a value and if so use it in the display rather than their username. If it doesn't have a value then we can default to the username.

So now using my previous example it will say "Hello, Soan. Welcome back to the site." We sincerely attribute the hack to danhounshell


Here are the steps to actually integrate GFC with your existing site:

Step 1

Register your site with GFC and get your site code from Friend Connect admin site
Copy and paste this code in your login.aspx page ( If you are targeting to only show the GFC log in button on your login.aspx page) or your any master page (if you want to show GFC log in button on all pages which are inheriting this master page).

The following code will load the GFC library and will initialize the necessary variables required for GFC.

We have given you example of both a simple GFC log in button and GFC member list + GFC log-in button. It is upto you which one you want to implement in your website. You can include any one or both at the same time. The given code will work in all cases.
<!-- Load the Google AJAX API Loader -->
 
<script type="text/javascript" src="http://www.google.com/jsapi"></script>

 
<!-- Load the Google Friend Connect javascript library. -->
 
<script type="text/javascript">
    google
.load('friendconnect', '0.8');
 
</script>

 
<!-- Initialize the Google Friend Connect OpenSocial API. -->
 
<script type="text/javascript">
  google.friendconnect.container.initOpenSocialApi({ site: '####################', onload: function(securityToken) { if (!window.timesloaded) { window.timesloaded = 1; initAllData(); } else { window.timesloaded++; } if (window.timesloaded > 1) { window.top.location.href = "http://YourSite.com/Login-GFC.aspx"; } /* your callback, which is passed a security token */ } });

 
</script>

THIS CODE IS TO RENDER THE GFC 'JOIN THIS SITE' BUTTON ONLY: For more button styles for GFC, look here:


 <!-- GFC - initialize the GFC sign-in button and other gadgets, if any-->
         <script type="text/javascript">
            function initAllData() {
               google.friendconnect.renderSignInButton({ 'id': 'gfc-button', 'text': 'Sign In with Google Friend Connect', 'style': 'long' });
            };
            
         </script>
THIS CODE IS TO RENDER BOTH THE MEMBER LIST AND A GFC 'JOIN THIS SITE' BUTTON:

   <!-- Include the Google Friend Connect javascript library. -->
         <script type="text/javascript" src="http://www.google.com/friendconnect/script/friendconnect.js"></script>
            <!-- Define the div tag where the gadget will be inserted. -->
            
            <!-- Render the gadget into a div. -->
                        <script type="text/javascript">
                           var skin = {};
                           skin['BORDER_COLOR'] = '#cccccc';
                           skin['ENDCAP_BG_COLOR'] = '#e0ecff';
                           skin['ENDCAP_TEXT_COLOR'] = '#333333';
                           skin['ENDCAP_LINK_COLOR'] = '#0000cc';
                           skin['ALTERNATE_BG_COLOR'] = '#ffffff';
                           skin['CONTENT_BG_COLOR'] = '#ffffff';
                           skin['CONTENT_LINK_COLOR'] = '#0000cc';
                           skin['CONTENT_TEXT_COLOR'] = '#333333';
                           skin['CONTENT_SECONDARY_LINK_COLOR'] = '#7777cc';
                           skin['CONTENT_SECONDARY_TEXT_COLOR'] = '#666666';
                           skin['CONTENT_HEADLINE_COLOR'] = '#333333';
                           skin['NUMBER_ROWS'] = '2';
                           
                           google.friendconnect.container.renderMembersGadget(
                         { id: 'div-5586681546069027486',
                            site: '####################'
                         },
                          skin);
                     </script>
            
         <!-- Google GFC Gadget- End -->

The <head> element of your website is a good place to paste this code.


Note that the ID number represented by #################### will actually be a unique number for each site, so you'll need to change this to your site's ID number if you want to copy and paste the code from this article. However, the "For Programmers" page in the Friend Connect admin site will have the correct values automatically inserted.

Create a div tag on your login/master page to show the GFC log in button only:


<!-- Define the div tag where the GFC log in will be inserted. -->

<div id="gfc-button" style="width:300px; border:1px solid #cccccc;"></div>  


Add the following code to your Log in /master page to show the list of GFC members and a log in to GFC button (Note that the div id is exactly same here as mentioned in above code to identify the div):

<!-- Define the div tag where the gadget will be inserted. -->

<div id="div-5586681546069027486" style="width:300px; border:1px solid #cccccc;"></div>   

 

Step 2:

Create a new page in your root directory with name: Login-GFC.aspx and add the following code to Login-GFC.aspx.cs . Note that Login-GFC.aspx does not need to have any code as this page will never be shown to user.

This page's code will be used to log-in only the GFC users. It will be fired when a user logs in through GFC and the GFC returns the successful log in details to your site.
Add the following code to this file:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;

using GFC.Components;
using GFC.util;
public partial class Login_GFC : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (HttpContext.Current.User.Identity.IsAuthenticated == true)
        {
            //User is already logged in with YourSite Id.
            //log the user out first from YourSite account.
           
            if (Session["isFriendConnect"] != null && (Boolean)Session["isFriendConnect"] != true)
            {
                FormsAuthentication.SignOut();               
            }
        }
        
                   
            string fcAuthToken = string.Empty;
            GFCUser user = null;
            if (Request.Cookies["fcauth####################"] != null) //Replace #################### with SiteId from GFC
            {
                fcAuthToken = Request.Cookies["fcauth####################"].Value;  //Replace #################### with SiteId from GFC
user = FriendConnectUtil.getViewer(fcAuthToken, true); Session["isFriendConnect"] = true; } else { Session["isFriendConnect"] = false; } Response.Redirect("~"); } }

Step 3:

Create a new page in your root directory with name LogOut-GFC.aspx and add the following code in LogOut-GFC.aspx itself.

This page will be used to log out the GFC user from your site.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="LogOut-GFC.aspx.cs" Inherits="LogOut_GFC" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Log Out GFC User</title>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <%--<!– Load the Google AJAX API Loader –>--%>
    <script type="text/javascript"> 
    //    <!– Load the Google Friend Connect javascript library. –>
    google.load('friendconnect', '0.8');
    </script>
    <script type="text/javascript"> 
//    <!– Initialize the Google Friend Connect OpenSocial API. –>
      google.friendconnect.container.setParentUrl('/' /* location of rpc_relay.html and canvas.html */);
      google.friendconnect.container.loadOpenSocialApi(
      {
         site: '####################', /* put your site ID here */
onload: function(securityToken) { if (!window.timesloaded) { window.timesloaded = 1; google.friendconnect.requestSignOut(); window.top.location.href = "/"; } else { window.timesloaded++; } if (window.timesloaded > 1) { window.top.location.href = "/"; } } } ); </script> </head> <body> <form id="form1" runat="server"> <div> </div> </form> </body> </html>
Note that LogOut-GFC.aspx.cs does not need to have any code.

Step 4:

Create a new file named FriendConnectUtil.cs in your ROOT/App_Code/Util/ directory. The full path should be ROOT/App_Code/Util/FriendConnectUtil.cs.

This class is used to interact with GFC and extract the user credentials from GFC and add it to your site's asp.net membership tables.
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Web.Security;

using http;
using GFC.Components;
using Jayrock.Json;

namespace GFC.util
{
  /// <summary>
  /// A utility class to handle FriendConnect-related requests.
  /// </summary>
  public class FriendConnectUtil 
  {
    /// <summary>
    /// Default public constructor.
    /// </summary>
    public FriendConnectUtil() 
    {
    }

    public static GFCUser getViewer(string fcAuthToken, bool addIfMissing)
    {
      return getFCUser(fcAuthToken, "@viewer", addIfMissing);
    }

    /// <summary>
    /// Gets the FriendConnect user corresponding to fcAuth or userId. If fcAuth
    /// is set, then it will use FriendConnect API calls to retrieve the FriendConnect
    /// user, otherwise it will fetch the user from database using userId, and
    /// then use its fcid along with 2-legged OAuth to fetch the FriendConnect
    /// user.
    /// </summary>
    /// <param name="fcAuthToken">The FriendConnect token.</param>
    /// <param name="userId">The local user id.</param>
    /// <param name="addIfMissing">Should a new user be created in local database if
    ///  there is no such user in the database? Default value of this param is True.
    ///  </param>
    /// <returns>The FriendConnect user.</returns>
    public static GFCUser getFCUser(string fcAuthToken, string userId, bool addIfMissing)
    {
      //HttpProvider httpProvider = (HttpProvider) ObjectFactory.getInstance("httpprovider");

       
      DefaultHttpProvider httpProvider = new DefaultHttpProvider() ;
      
      string url = "";
      // try to retrieve the user using fcAuth
      if (!string.IsNullOrEmpty(fcAuthToken))
      {
        url = string.Format("http://www.google.com/friendconnect/api/people/{0}/@self?fcauth={1}", 
            userId, fcAuthToken);
      }
      
      string response = httpProvider.send(url, "GET", "", null);
      
      GFCUser retVal = null;

      if(!string.IsNullOrEmpty(response))
      {
        JsonTextReader reader = new JsonTextReader(new StringReader(response));
        JsonObject data = new JsonObject();
        data.Import(reader);
        
       
        retVal = new GFCUser();
        JsonObject entry = (JsonObject)data["entry"];
        

        retVal.UserName = entry["id"].ToString();
        
        retVal.DisplayName = entry["displayName"].ToString();
      

        //Now see if the user already exists, if not create them
        if (Membership.GetUser(retVal.UserName) == null)
        {
            MembershipCreateStatus membershipCreateStatus;
            MembershipUser user = Membership.CreateUser(retVal.UserName,
                                                        "1234",
                                                        /*Common.GetRandomString(5, 7),*/
                                                        "PleaseSpecify@YOURSITE.com",
                                                        "This is a Google friend connect account. Please Log in with your Friend connect account.",
                                                        "GFC",
                                                        true,
                                                        out membershipCreateStatus);
       
            if (membershipCreateStatus != MembershipCreateStatus.Success)
            {

               //Some way to show that some error has occured.
            }
            else
            {   //Roles to which new user should be added
                Roles.AddUserToRole(user.UserName, "Members");
                
            }
            //Signifies that it is a GFC user account.
            user.Comment = retVal.DisplayName;
            Membership.UpdateUser(user); 
        }

        // Use FormsAuthentication to tell ASP.NET that the user is now logged in,  
        // with the GFC user name as their username. 
        FormsAuthentication.RedirectFromLoginPage(retVal.UserName, true /*chkRememberMe.Checked*/);

        
      
      }
      return retVal;
    }

  
  }
}


Step 5:

Create a new file named DefaultHttpProvider.cs in your ROOT/App_Code/http/ directory.
The full path should be ROOT/App_Code/http/DefaultHttpProvider.cs.

This class is used as a helper class in communicating with GFC. Add the following code to this file:

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web;

namespace http {
  /// <summary>
  /// An implementation of HttpProvider that System.Net.WebRequest to provide HTTP services. 
  /// </summary>
  //public class DefaultHttpProvider : HttpProvider {
    public class DefaultHttpProvider 
    {
    /// <summary>
    /// Sends an HTTP request to the server.
    /// </summary>
    /// <param name="url">The request url.</param>
    /// <param name="method">The HTTP method.</param>
    /// <param name="postBody">The POST body, if the method is POST. Ignored if method is
    /// not POST.</param>
    /// <param name="headers">The HTTP header parameters as an array.</param>
    /// <returns>The response as a string, or empty string if response can't be obtained.</returns>
    public string send(string url, string method, string postBody, string[] headers) {
      HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(url);
      request.Method = method;

      if (method == "POST") {
        Stream outStream = request.GetRequestStream();
        byte[] contents = Encoding.UTF8.GetBytes(postBody);
        outStream.Write(contents, 0, contents.Length);
        outStream.Close();
        request.ContentLength = contents.Length;
      }

      if (headers != null) {
        foreach (string header in headers) {
          request.Headers.Add(header);
        }
      }

      try {
        HttpWebResponse response = (HttpWebResponse) request.GetResponse();
        StreamReader inStream = new StreamReader(response.GetResponseStream());
        string contents = inStream.ReadToEnd();
        inStream.Close();
        return contents;
      } catch (Exception ex) {
        return "";
      }
    }
  }
}


Step 6:

Create a new file named GFCUser.cs in your 'ROOT/App_Code/Components/' directory.

The full path should be ROOT/App_Code/Components/GFCUser.cs.

This class defines a temporary GFC style user.

using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace GFC.Components { /// <summary> /// Represents a User registered to chow-down. /// </summary> public class GFCUser { /// <summary> /// Default public constructor. /// </summary> public GFCUser() { //this.id = 0; this.UserName = string.Empty; this.password = string.Empty; this.email = string.Empty; this.displayName = string.Empty; //this.fcid = ""; } /// <summary> /// User name. /// </summary> public string UserName { get { return userName; } set { userName = value; } } /// <summary> /// User's password. /// </summary> public string Password { get { return password; } set { password = value; } } /// <summary> /// User's email. /// </summary> public string Email { get { return email; } set { email = value; } } public string DisplayName { get { return displayName; } set { displayName = value; } } /// <summary> /// User name. /// </summary> private string userName; /// <summary> /// User's password. /// </summary> private string password; /// <summary> /// User's email. /// </summary> private string email; private string displayName; } }

Step 7:

Download the follwing file, unzip it and copy the following files to your 'ROOT/bin' folder.

Jayrock.Json.dll
Jayrock.Json.dll.refresh

JayrockJason.zip (39.03 kb)

Step 8:

You can use the following function to get the GFC user's display name. This function will work for getting both
  1. Normal asp.net user and
  2. GFC user registered with your site :


static public string getDisplayNameForUser(string userName)

    {
        string dispName = string.Empty;

        MembershipUser user = Membership.GetUser(userName);
        if (user != null)
        {
            if (user.Comment != null)
            {
                //If the comment is NOT NULL, then the user is a GFC account holder and comment is his/her
                // display name.
                dispName = user.Comment;
            }
            else
            {
                dispName = user.UserName;
            }
        }
        return (dispName);
    }



That's it. You are done. just run this site and you will be able to see the GFC log-in button on your site. ENJOY!!


This is a QR code for this article. It contains the link for this article and can be scanned through a QR code reader application in your mobile to quickly open it in any mobile browser.

Would you like to share this article?


For more helpful articles like this, subscribe to our free newsletter or stay connected on social networks:

SUBSCRIBE
Subscribe to AM22 tech in Reader or by Email
Sign up for our updates in Email (Free):

 

Have questions? Write into comments or ask in forum