经典 ASP 与 Facebook 网站功能集成






4.91/5 (27投票s)
将 Facebook 网站工具集成添加到您的 ASP 身份验证中
注意
这段代码相当陈旧,已不再维护,但其中包含了一些可以从中学习的优秀编码实践和技巧,因此我将保留这篇文章。如果您想将您的经典 ASP 页面连接到 Facebook,请参阅我的文章: https://codeproject.org.cn/Articles/333706/Classic-ASP-and-Facebook-Graph-API。
引言
在集成 Facebook 时,我总是不得不求助于 PHP 或 .NET 来完成这项工作。新的 Facebook for Websites 工具集结合一些开源解决方案,可以轻松地用 ASP 完成。在这篇文章中,我将展示它是如何工作的,需要哪些工具,以及最后如何将其集成到您网站现有的登录框架中。
注意:此代码已针对 Facebook oAuth 2.0 进行修改。它不再使用 JavaScript 组件进行登录。如果您过去曾使用过此库,请仔细阅读本文,您会发现过程比以前容易得多,但需要略有不同的设置。请阅读结尾处标有“转换 2012 年之前的代码”的部分,以获取转换现有代码的技巧。
背景
我发现了两个非常棒的工具,可以帮助解决将 Facebook 的 PHP 文章翻译成 VBScript 的问题(Facebook 文章可以在 此处找到)。
首先是 Troy Foster 和 Doug Crawford 的 json2.asp 库。这个解决方案的亮点在于它利用了经典 ASP 一个常被遗忘的功能:只要它们被隔离在 <script runat="server"></script>
块中,就可以同时运行 JScript 和 VBScript。通常,IIS 服务器配置为使用 VBScript,因此只有在要指定非服务器默认语言时才需要特殊的 runat 标签。对于 VBScript,在大多数 IIS 服务器上,<% %>
标签仍然可以正常工作。
我发现的第二个酷炫工具是 Flangy Development 对 URLDecode
的实现(可在 此处找到)。稍后我将详细介绍,但相信我,这真的很棒!
还有一个非常有用的库是来自 http://www.frez.co.uk 的 MD5 加密。我将其封装到了一个名为“encrypt
”的类中。
为了完善我为这个解决方案收集的工具,还有 Microsoft 的 KB246067,它提供了一种按键对字典对象进行排序的方法,以模拟 PHP 的 ksort
。
Using the Code
Facebook 的部分验证需要 MD5 来操作,还需要先对 cookie 值列表进行排序,然后将它们组合成一个长字符串,其中包含名为 payload 的“variable=data”集。值本身是 URLEncoded
的,因此需要一个 URLDecode
函数。有很多脚本可以执行此操作;我被这个示例中使用的脚本的优雅所吸引。
要利用 Facebook 身份验证,您首先需要在 http://developers.facebook.com/setup/ 注册您的网站。注册后,您将获得一个 API 密钥和一个应用程序密钥。打开源代码中的 fb_app.asp 文件,并将 FACEBOOK_APP_ID
变量填充为 API 密钥,将 FACEBOOK_SECRET
变量填充为应用程序密钥。
您还需要在您使用 Facebook 身份验证的页面中包含两个库:JSON2
库和 fb_app.asp 库。
使用此标签包含 JSON2 库
<script language="JavaScript" runat="server" src="json2.asp"></script>
这是等同于用于服务器端包含的 #INCLUDE FILE 的脚本标签。fb_app.asp 库使用标准的 include 方式包含,如下所示:
<!-- #INCLUDE FILE="fb_app.asp" -->
如果您想将 Facebook 身份验证机制与您现有的身份验证机制集成,您需要在 fb_app.asp 的 fb_main
函数中包含代码,以更新/添加数据库中的用户信息,并根据 FB userid
进行身份验证。
服务器端就完成了。在您的 HTML 标记中,您需要包含 Facebook JavaScript 库以及一个用于登录按钮的锚标记。
<a href="myfacebookauthpage.asp">Login using Facebook</a>
上面的锚标记应该放置在您希望它在 HTML 中显示的位置。
在您的登录代码中,包含以下两行以执行身份验证:
strJSON = get_json_cookie( cookies("access_token") ) ' this is a function in fb_app.asp
Set user = JSON.parse( strJSON ) ' this is the JSON object from JSON2.ASP
现在,用户对象将具有您可以访问的 name、id 和 email 属性(user.id
)。
您的登录页面现在已启用 FB 功能!
更深入地了解 Facebook 交互
FACEBOOK_SCOPE 值(在 facebook_app.asp 中)默认包含请求访问访问者电子邮件地址和动态消息的权限。这样做是因为在 Facebook 用户允许您的应用程序时,只能获得姓名和家乡信息。在 Facebook 用户批准您的请求之前,会告知用户您希望访问的字段。下面的示例显示了此登录链接的提示。
此文件是“前端”,代表您的登录页面。它包含关键的服务器端库。您需要添加的任何库以及支持 Facebook 登录按钮的代码,如下所示。
当用户允许您的应用程序时,Facebook 会为您的网站创建一个 cookie,授予您访问 FB userid
和访问令牌的权限。访问令牌是使您能够检索完整允许信息集的密钥。这需要对 Facebook 进行服务器端调用。这里的挑战在于 Facebook 返回的是 JSON 格式而不是 XML。因此,您需要将 JSON 转换为 VBScript 可以操作的内容。这时就需要第一个很棒的工具:JSON2.ASP。下面的代码是 Facebook 返回的 JSON 示例。
{
"id": "9",
"name": "FirstName LastName",
"first_name": "FirstName",
"last_name": "LastName",
"link": "https://#/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"
}
JSON2.ASP 库巧妙地利用服务器端的 Jscript 将 JSON 解析成一个对象,然后可以在 VBScript 中引用该对象。这一切之所以成为可能,是因为 ASP 允许 Jscript 对象和 VBScript 交互(尽管是在某种程度上比较初级的)。
所以,我们只需要使用以下代码从 Facebook 获取页面数据作为一个 string
,并将其作为 string
传递给 JSON 对象:
strJSON = get_json_cookie( cookies("access_token") ) ' this is a function in fb_app.asp
Set user = JSON.parse( strJSON ) ' this is the JSON object from JSON2.ASP
现在,用户对象已填充。您可以访问用户的数据来注册/更新您的数据库。在代码示例中,我输出了(response.write
)一组常见的注册变量,以帮助您入门。
您现在可以集成到您的数据库中(参见下面的建议)。
数据库集成建议
由于每个人的登录例程略有不同,我将提供最基本的登录机制框架,并展示如何添加 FB_APP
。在经典的数据库驱动的身份验证场景中,用户会访问登录页面,在文本框中输入用户名和密码,然后单击按钮进行登录。登录提交后,ASP 页面将根据登录名和密码查找用户记录,如果登录无效(recordset
为空),则会提示用户重试。如果登录有效,脚本将设置一个 cookie 或会话变量来指示登录,然后继续进入主页。代码看起来像这样。
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
首先要做的是在您的用户表中添加一个名为“fb_userid
”的字段,类型为 bigint。这将用于存储 Facebook userid
并将其与您数据库中的 userid
相关联。然后修改您的登录过程,首先尝试根据 Facebook UserID
查找用户,如果找到用户则设置会话,如果未找到用户则注册他们并通过 Facebook UserID
获取其用户记录。以下是上述基本函数的修改版本,它正是这样做的。请仔细研究它,并将其集成到您自己的登录代码中。
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
' it's a post/standard login
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
' attempt a Facebook style login
' do we have an FB Cookie
if request.cookies("fbs_" & FACEBOOK_APP_ID)="" then
' No Facebook login
else
' We have Facebook info create a dictionary to contain the cookie info
set fbcookie = get_facebook_cookie( FACEBOOK_APP_ID, FACEBOOK_SECRET )
if fbcookie.count > 0 then
'' Use the access token to get the userinfo
'' as a JSON a string from Facebook
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
' record is empty add user
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
关注点
我认为最值得关注的是 Flangy Development 的 URLDecode
例程。
' An inverse to Server.URLEncode
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
' Replacement function for the above
function URLDecodeHex(match, hex_digits, pos, source)
URLDecodeHex = chr("&H" & hex_digits)
end function
我认为使用 GetRef
将函数指针传递给正则表达式的做法特别巧妙。
转换 2012 年之前的代码
如果您以前使用过此库,您会知道 Facebook 在 2012 年的更新破坏了该库。截至 2012 年 1 月 16 日,我已经更新了代码,使其能够与新的 Facebook 配合使用。除了修复代码之外,我还利用了 oAuth 2.0,这在一定程度上简化了设置。以下提示将概述需要更改的区域。
- 移除 Facebook 的 JavaScript 库
您不再需要引用 Facebook 库。身份验证现在完全由服务器端代码处理。 - 移除 FB 标记
用于启用 Facebook 的 FB 标记已被指向您的身份验证页面的链接所取代。请务必在您的登录页面中包含 FB_APP.ASP 库。现在,您创建一个链接:<a href="myfbloginpage.asp">使用 Facebook 登录</a>,而不是 FB 标记。 - oAuth 2.0
为了避免代码将来出现中断,我整合了 oAuth 2.0 身份验证机制。上述两个更改是此更改的特定部分。 - Scope 移至服务器端变量
Scope 已移至服务器端变量(作为移除 FB 标记的结果)。因此,您现在需要在 FB_APP.ASP 页面的 FACEBOOK_SCOPE 变量中设置 scope。 此外,您需要将 FACEBOOK_REDIR_URL 设置为您网站上处理 Facebook 身份验证的页面。 FACEBOOK_REDIR_URL 在 V3.1 中使用 GetRedirURL() 函数自动创建。这允许任何具有 Facebook 交互的页面自动登录。
这样应该就能正常工作了。我在我自己的几个网站上测试过,效果很好。但我无法测试所有可能的情况。因此,如果您在您的网站上遇到问题,请告诉我,我会尽力提供建议。
相关文章
历史
- 2010 年 7 月 16 日:初始发布
- 2012 年 1 月 16 日:针对 oAuth 2.0 (V3.0) 修改
- 2012 年 1 月 16 日:发布了错误修复 (V3.0.1)
- 2012 年 1 月 25 日:3.1 版本 - 多项错误修复,不再需要设置重定向 URL。Cookie 身份验证令牌每小时过期,强制 fb_app.asp 请求新令牌。
- 2012 年 3 月 1 日:添加了指向新文章的链接。