Facebook“Like”与否判断
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Facebook“Like”与否判断
⽤例:
在开发facebook应⽤的过程当中,经常要判断facebook⽤户对当前应⽤的“Like”状态,从⽽显⽰不同的内容。
⼀个典型的例⼦是在表单上放上⼀个遮罩层(通常是⼀个id为shade的div),⽤户⽆法透过遮罩层点击输⼊框,从⽽诱导⽤户点击facebook 菜单上的 “Like”按钮,页⾯进⾏⼀次跳转,在跳转的过程当中,我们可以从facebook返回的信息当中获得“Like”的状态,进⽽判断是否取消显⽰遮罩层。
总体思想:
在嵌⼊facebook的应⽤前端页⾯,加⼊以下代码(加在body的closing tag之前):
<div id="fb-root"></div>
<script type="text/javascript" src="/en_US/all.js"></script>
<script type="text/javascript">
FB.init({
appId: [facebook_app_id], // 注意替换相应的facebook app id
status: true,
cookie: true,
xfbml: true,
oauth: true
});
FB.Canvas.setAutoResize(10); // 这句调⽤facebook api来调整嵌⼊的窗⼝⼤⼩,不是必要的但⼀般最好加上
</script>
之后,每当刷新facebook应⽤页⾯的时候,facebook都会在request⾥加上⼀个叫做“signed_request”的parameter,它是由⼀个“点”符号连接起来的两个乱码字符串,看起来像这样(注意“点”前后没有空格,这边加上空格只是⽅便阅读):
vlXgu64BQGFSQrY0ZcJBZASMvYvTHu9GQ0YM9rjPSso . eyJhbGdvcml0aG0iOiJITUFDLVNIQTI1NiIsIjAiOiJwYXlsb2FkIn0
前半部分是⼀个加密的字符串, 后半部分是⼀个编码的JSON object.
后台实现:
通过将后半部分通过密钥(facebook application secret)加密,将得出的字符串与前半部分进⾏⽐较,如果相同则后半部分所包含的JSON object是有效的,进⽽将后半部分进⾏base64url解码,得出真正的JSON object。
JSON object中⼀定有⼀个名为“like”的键,如果其值不为空的话,说明⽤户已经点击过“Like”按钮了。
注意:键值在不同语⾔中不同,“liked”(c#)或 “1”(php),具体代码⽰例如下:
PHP:
<?php
$application_secret = [facebook_application_secret]; // 注意替换相应的facebook application secret
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return$data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
>
$payloadArray = parse_signed_request($_REQUEST["signed_request"], $application_secret);
<div id="shade" style="<?php
if($payloadArray["page"]["liked"] == "1") echo "display:none;"; // 取消遮罩层
else echo "display:block;"; // 显⽰遮罩层
>"> <div id="like-enter"><span>Like us to enter the competition</span></div>
</div>
C#:
private static string APPLICATION_SECRET = [facebook_application_secret]; // 注意替换相应的facebook application secret
protected void Page_Load(object sender, EventArgs e)
{
if (Request.Params["signed_request"] != null)
{
string decodedPayloadString = ValidateSignedRequest(Request.Params["signed_request"]);
string[] payloadArray = decodedPayloadString.Split(',');
string liked = payloadArray[3];
string likeValue = liked.Substring(7, 5);
if (likeValue == ":true")
{
div_shade.Visible = false; // 取消遮罩层
}
else
{
div_shade.Visible = true; // 显⽰遮罩层
}
}
}
private string ValidateSignedRequest( string signedRequest ) {
string[] signedRequestArray = signedRequest.Split( '.' );
string expectedSignature = signedRequestArray[0];
string payload = signedRequestArray[signedRequestArray.Length - 1];
byte[] Hmac = SignWithHmac( UTF8Encoding.UTF8.GetBytes( payload ), UTF8Encoding.UTF8.GetBytes( LikeDetection.APPLICATION_SECRET ) );
string HmacBase64 = ToUrlBase64String( Hmac );
bool result = (HmacBase64 == expectedSignature);
if (result)
{
string decodedPayload = System.Text.UTF8Encoding.UTF8.GetString( FromBase64ForUrlString( payload ) );
}
return decodedPayload;
}
private byte[] SignWithHmac( byte[] dataToSign, byte[] keyBody ) {
using ( System.Security.Cryptography.HMACSHA256 hmacAlgorithm = new System.Security.Cryptography.HMACSHA256( keyBody ) ) {
puteHash( dataToSign );
return hmacAlgorithm.Hash;
}
}
private string ToUrlBase64String( byte[] Input ) {
return Convert.ToBase64String( Input ).Replace( "=", String.Empty ).Replace( '+', '-' ).Replace( '/', '_' );
}
private byte[] FromBase64ForUrlString( string base64ForUrlInput ) {
int padChars = ( base64ForUrlInput.Length % 4 ) == 0 ? 0 : ( 4 - ( base64ForUrlInput.Length % 4 ) );
StringBuilder result = new StringBuilder( base64ForUrlInput, base64ForUrlInput.Length + padChars );
result.Append( String.Empty.PadRight( padChars, '=' ) ).Replace( '-', '+' ).Replace( '_', '/' );
return Convert.FromBase64String( result.ToString() );
}
还值得注意的很重要⼀点是:通过以上⽅法获取的“Like”的值,只有在加载facebook应⽤的home page的时候,也就是说,只有在facebook outer frame刷新的时候才能获取到,如果在facebook内嵌的我们⾃⾏搭建的iframe内进⾏跳转,这个值是⽆法被再次获取得到的,因此如果想要之后得到“Like”的状态,就必须⽤到Cookie或Session或通过URL传值的⽅法保留这个信息。