NOTE
This code is fairly old and not maintained anymore, but there are good examples of coding practices and tricks that you can learn from so I'll keep the article alive. However if you are looking to connect your classic ASP page to Facebook please see my article: http://www.codeproject.com/Articles/333706/Classic-ASP-and-Facebook-Graph-API.
Introduction
When integrating with Facebook, I've always had to resort to PHP or .NET to get the job done. The new Facebook for Websites tool set combined with a few open source solutions makes this a snap with ASP. In this article, I hope to show you how it works, what tools you need to pull together and finally a suggestion for how to integrate with your website's existing login framework.
NOTICE: This code was revised for Facebook oAuth 2.0. It no longer uses the javascript components for logging in. If you have used this library in the past please read through the article you'll see the process is much easier than before but requires a slightly different setup. Read the section at the end titled "Converting Pre 2012 Code" for tips on converting existing code.
Background
There are two really slick tools I found to help solve the problem of translating Facebook's article from PHP to VBScript (the Facebook article can be found here).
First is the json2.asp library by Troy Foster and Doug Crawford. What is slick about this solution is that it takes advantage of an often forgotten feature of Classic ASP: you can run JScript and VBscript together as long as they are isolated in <script runat="server"></script>
blocks. Usually, an IIS server is configured for vbscript so you only need the special runat tags when you want to specify a language other than the server default. For VBScript, <% %>
tags should still work fine on most IIS servers.
The second cool tool I found is Flangy Development's implementation of URLDecode
(found here). I'll go into the details later, but trust me, this is really slick!
A third library is also very useful MD5 encryption from http://www.frez.co.uk. I wrapped this into a class "encrypt
".
To round out the tools I pulled together for this solution is Microsoft's KB246067 which provides a way to sort a dictionary object by key to emulate PHP's ksort
.
Using the Code
Part of Facebook's validation requires MD5 to operate, it also requires that the list of cookie values is sorted first and assembled in a long string of variable=data sets called the payload. The values themselves are URLEncoded
thus the need for an URLDecode
function. There are many scripts available to do this; I was enamored by the elegance of the one I use in this example.
To leverage Facebook authentication, you need to first register your website on Facebook at http://developers.facebook.com/setup/. Once registered, you'll get an API Key and an Application Secret. Open fb_app.asp from the source code and populate the variables FACEBOOK_APP_ID
with the API Key and FACEBOOK_SECRET
with the application secret.
You also need to include two libraries in your pages that utilize Facebook authentication: The JSON2
library and the fb_app.asp library.
You include the JSON2 library using this tag:
<script language="JavaScript" runat="server" src="json2.asp"></script>
This is the script tag equivalent to a #INCLUDE FILE as used for server side includes. The fb_app.asp library is included using a standard include as follows:
If you want to integrate the Facebook authentication mechanism with your existing authentication mechanism, you need to include code in the fb_main
function of fb_app.asp that updates/adds the user information in your database and authenticates based on FB userid
.
That takes care of the server side. In your HTML markup, you need to include the Facebook JavaScript library along with an anchor tag for your login button.
<a href="myfacebookauthpage.asp">Login using Facebook</a>
The anchor tag above should be placed where you want it to display in your HTML.
In your login code, include the following two lines to perform the authentication:
strJSON = get_json_cookie( cookies(<span lang="en-us">"</span>access_token") )
Set user = JSON.parse( strJSON )
The user object will now have name, id and email properties that you can access (user.id
).
Your login page is now FB enabled!
A Closer Look at Facebook Interaction
The FACEBOOK_SCOPE value (found in facebook_app.asp) includes a request for permission to access the visitors' email address and stream by default. This is done because only the name and hometown information in the default dataset is otherwise available when a Facebook user allows your application. The Facebook user is told what fields you wish to access before approving your request. The example below shows the prompt for this login link.
This file is the “front end" and represents your login page. It includes the key server side libraries. Any libraries you need to add and the code necessary to support the Facebook login button as shown below:
When the user allows your application, Facebook creates a cookie for your website that grants you access to the FB userid
and an access token. The access token is the key that enables you to retrieve the full set of allowed information. This requires a server-side call to Facebook. The challenge here is that Facebook returns JSON notation rather than XML. As such, you need to convert the JSON into something that can be manipulated by VBScript. Enter the first groovy tool: JSON2.ASP. The code below is an example of JSON returned by Facebook.
{
"id": "9",
"name": "FirstName LastName",
"first_name": "FirstName",
"last_name": "LastName",
"link": "http://www.facebook.com/firstname.lastname",
"about": "Rugby and Brats, enough said.",
"birthday": "12/02",
"hometown": {
"id": 9999999999999999,
"name": "Chicago, Illinois"
},
"location": {
"id": 9999999999999999,
"name": "Chicago, Illinois"
},
"bio": "I like cheese",
"quotes": "Bears, Beats, Battlestar Galactica.",
"gender": "female",
"timezone": -6,
"locale": "en_US",
"verified": true,
"email": "firstname.lastname@mysite.com",
"updated_time": "2010-06-05T16:22:56+0000"
}
The JSON2.ASP library cleverly utilizes Jscript on the server side to parse the JSON into an object that can then be referenced in VBScript. This is all made possible because ASP enables Jscript objects and VBScript to interact (albeit at a somewhat primitive level).
So all we have to do is get the page data as a string
from Facebook and pass it as a string
to the JSON object with the following code:
strJSON = get_json_cookie( cookies("access_token") )
Set user = JSON.parse( strJSON )
The user object is now populated. You can access the data from the user to register/update your database. In the code example, I write (response.write
) a list of variables common to registration to get you started.
You can now integrate with your DB (see suggestions below).
Suggestions for DB Integration
Since everybody's login routine is a little different, I'll provide the most basic framework of a login mechanism and show how FB_APP
can be added. In a classic database-driven authentication scenario, a user would visit a login page and type username and password into textboxes, then click a button to login. On submission of the login, the ASP page would look up the user record based on login and password if the login is invalid (recordset
is empty) the user is prompted to try again. If the login is valid, the script would set a cookie or a session variable to indicate a login, then proceed to the homepage. The code would look something like this.
Function do_login()
sUser = request.form("login")
sPass = request.form("pass")
Set conn = createobject("adodb.connection")
Conn.connectionstring="your connection string"
Conn.open
Set rs = conn.execute( "SELECT * FROM users WHERE login='" _
& sUser & "' and password='" & sPass & "';") If rs.eof then
Rs.close
Conn.close
Response.write "invalid login try again"
Else
Session("userid")=rs("userid")
Rs.close
Conn.close
Response.redirect("securepage.asp")
End If
End function
The first thing to do is add a field to your user table “fb_userid
" as a bigint. This will be used to store the Facebook userid
and correlate it back to a userid
in your database. Then modify your login process to first try and lookup the user based on Facebook UserID
, if a user is found set the session, if the user is not found register them and get their user record by Facebook UserID
. Here is a modified version of the basic function above that does just that. Study it and work it into your own login code.
Function do_login()
dim conn
dim rs
dim sUser
dim sPass
dim sFBID
dim user
dim strJSON
dim fbcookie
dim SQL
Set conn = createobject("adodb.connection")
Conn.connectionstring="your connection string"
Conn.open
if request.servervariables("request_method")="POST" then
sUser = request.form("login")
sPass = request.form("pass")
Set rs = conn.execute( "SELECT userid FROM users WHERE login='" & sUser & _
"' and password='" & sPass & "';")
If rs.eof then
Rs.close
Response.write "invalid login try again"
Else
Session("userid")=rs(0)
Rs.close
conn.close
set conn = nothing
Response.redirect("securepage.asp")
End If
else
if request.cookies("fbs_" & FACEBOOK_APP_ID)="" then
else
set fbcookie = get_facebook_cookie( FACEBOOK_APP_ID, FACEBOOK_SECRET )
if fbcookie.count > 0 then
sToken = fbcookie("access_token")
url = "https://graph.facebook.com/me?access_token=" & sToken
strJSON = get_page_contents( URL )
set user = JSON.parse( strJSON )
set rs = conn.execute("SELECT userid FROM users _
WHERE fb_userid=" & user.id )
if rs.eof then
rs.close
set rs = nothing
SQL = "INSERT INTO users (first_name,last_name,email,fb_userid) " & _
"VALUES( " & _
" '" & replace( user.first_name, "'", "''" ) & "', " & _
" '" & replace( user.last_name, "'", "''" ) & "', " & _
" '" & replace( user.email, "'", "''" ) & "' " & _
user.id & ");"
conn.execute( SQL )
set rs = conn.execute("SELECT userid FROM users _
WHERE fb_userid=" & user.id )
session("userid")=rs(0)
rs.close
set rs = nothing
else
session("userid")=rs(0)
rs.close
set rs = nothing
end if
else
response.write "Facebook Authentication Failed"
end if
end if
end if
conn.close
set conn = nothing
End function
Points of Interest
I think the key point of interest is the routine for URLDecode
from Flangy Development.
function URLDecode(str)
dim re
set re = new RegExp
str = Replace(str, "+", " ")
re.Pattern = "%([0-9a-fA-F]{2})"
re.Global = True
URLDecode = re.Replace(str, GetRef("URLDecodeHex"))
end function
function URLDecodeHex(match, hex_digits, pos, source)
URLDecodeHex = chr("&H" & hex_digits)
end function
I thought the use of GetRef
to pass a function pointer to a regular expression was particularly clever.
Converting Pre 2012 Code
If you used this library before you know that 2012 update for facebook broke the library. As of Jan 16, 2012 I have updated the code to function with the new Facebook. In addition to fixing the code I took advantage of oAuth 2.0 which simplifies the setup somewhat. The tips below will outline the areas that need to change.
- Elimination of Facebook's Javascript Library
You no longer need to reference the facebook library. Authentication is all handled with server-side code. - Elimination of FB Markup
The FB markup tag to enable Facebook has been replaced with a link to your authentication page. Be sure to include the FB_APP.ASP library in your login page. Now you create a link: <a href="/KB/asp/myfbloginpage.asp">Use Facebook to Login</a> instead of the FB markup. - oAuth 2.0
To avoid future breakage of the code, I incorporated oAuth 2.0 mechanism of authentication. The above two changes are specifically part of this change. - Scope moved to Server Side Variable
The scope was moved to a server side variable (as a result of removing the FB markup). So you now need to set the scope in the FACEBOOK_SCOPE variable of the FB_APP.ASP page. In addition you need to set the FACEBOOK_REDIR_URL to the page on your website that handles facebook authentication. FACEBOOK_REDIR_URL is automatically created in V3.1 using the GetRedirURL() function. This allows any page with Facebook interaction to automatically login.
That should do the trick. I tested this out on a couple of my own sites and it worked well. However I can't test for every possible scenario. As such let me know if you experience problems with your site and I'll do my best to provide advice.
Related Articles
Classic ASP and Facebook Graph API
History
- 16th July, 2010: Initial post
- 16th January 2012: Revised for oAuth 2.0 (V3.0)
- 16th January 2012: Posted bug fix (V3.0.1)
- 25th January 2012: Version 3.1 - Several bug fixes, no longer need to set redirection URL. Cookie authentication token expires hourly forcing the fb_app.asp to request a new token.
- 1st March 2012: Added a link to the new article.