65.9K
CodeProject 正在变化。 阅读更多。
Home

经典 ASP 与 Facebook 网站功能集成

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (27投票s)

2010年7月16日

CDDL

8分钟阅读

viewsIcon

1192947

downloadIcon

7374

将 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.aspfb_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,这在一定程度上简化了设置。以下提示将概述需要更改的区域。

  1. 移除 Facebook 的 JavaScript 库
    您不再需要引用 Facebook 库。身份验证现在完全由服务器端代码处理。
  2. 移除 FB 标记
    用于启用 Facebook 的 FB 标记已被指向您的身份验证页面的链接所取代。请务必在您的登录页面中包含 FB_APP.ASP 库。现在,您创建一个链接:<a href="myfbloginpage.asp">使用 Facebook 登录</a>,而不是 FB 标记。
  3. oAuth 2.0
    为了避免代码将来出现中断,我整合了 oAuth 2.0 身份验证机制。上述两个更改是此更改的特定部分。
  4. Scope 移至服务器端变量
    Scope 已移至服务器端变量(作为移除 FB 标记的结果)。因此,您现在需要在 FB_APP.ASP 页面的 FACEBOOK_SCOPE 变量中设置 scope。 此外,您需要将 FACEBOOK_REDIR_URL 设置为您网站上处理 Facebook 身份验证的页面。 FACEBOOK_REDIR_URL 在 V3.1 中使用 GetRedirURL() 函数自动创建。这允许任何具有 Facebook 交互的页面自动登录。

这样应该就能正常工作了。我在我自己的几个网站上测试过,效果很好。但我无法测试所有可能的情况。因此,如果您在您的网站上遇到问题,请告诉我,我会尽力提供建议。

相关文章

经典 ASP 和 Facebook Graph API

 

历史

 

  • 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 日:添加了指向新文章的链接。
© . All rights reserved.