2012-07-11 88 views
2

我的目標是使用FB登錄按鈕,以便FB用戶可以登錄到我的ASP.NET MVC 3網站。看來Facebook的C#SDK最近已經發生了變化,所有的old examples都不能用於新版本。我嘗試了一天,讓他們工作...我正在關閉本教程Getting Started with the Facebook C# SDK for ASP.NET(無法)開始使用Facebook C#SDK

當前當我瀏覽http://localhost:8033/它似乎自動登錄(即使重新啓動Chrome後)因爲它顯示「我的名字使用我的應用程序名稱」並顯示我的照片。我預計它會顯示一個FB登錄按鈕。當我去http://localhost:8033/Home/About時,出現Session["AccessToken"]爲空的錯誤(這很有意義,因爲它顯然沒有設置)。

這是我有:

HomeController.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using Facebook; 

namespace FacebookTest.Controllers 
{ 
    public class HomeController : Controller 
    { 
     public ActionResult Index() 
     { 
      ViewBag.Message = "Welcome to ASP.NET MVC!"; 

      return View(); 
     } 

     public ActionResult About() 
     { 
      var accessToken = Session["AccessToken"].ToString(); 
      var client = new FacebookClient(accessToken); 
      dynamic result = client.Get("me", new { fields = "name,id" }); 
      string name = result.name; 
      string id = result.id; 

      ViewBag.Message = "Hello id: " + id; 

      return View(); 
     } 

     [AcceptVerbs(HttpVerbs.Post)] 
     public ActionResult FacebookLogin(HttpContext context) 
     { 
      var accessToken = context.Request["accessToken"]; 
      context.Session["AccessToken"] = accessToken; 

      return RedirectToAction("About"); 
     } 
    } 
} 

Index.cshtml

@{ 
    ViewBag.Title = "Home Page"; 
} 

<h2>@ViewBag.Message</h2> 
<p> 
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. 
</p> 

<div id="fb-root"></div> 
<script> 
    window.fbAsyncInit = function() { 
     FB.init({ 
      //appId: 'YOUR_APP_ID', // App ID 
      appId: '<MY-NUMBER-REMOVED>', // App ID 
      status: true, // check login status 
      cookie: true, // enable cookies to allow the server to access the session 
      xfbml: true // parse XFBML 
     }); 

     // Additional initialization code here 
     FB.Event.subscribe('auth.authResponseChange', function (response) { 
      if (response.status === 'connected') { 
       // the user is logged in and has authenticated your 
       // app, and response.authResponse supplies 
       // the user's ID, a valid access token, a signed 
       // request, and the time the access token 
       // and signed request each expire 
       var uid = response.authResponse.userID; 
       var accessToken = response.authResponse.accessToken; 

       // TODO: Handle the access token 
       // Do a post to the server to finish the logon 
       // This is a form post since we don't want to use AJAX 
       var form = document.createElement("form"); 
       form.setAttribute("method", 'post'); 
       //form.setAttribute("action", '/FacebookLogin.ashx'); 
       form.setAttribute("action", '/Home/FacebookLogin'); 

       var field = document.createElement("input"); 
       field.setAttribute("type", "hidden"); 
       field.setAttribute("name", 'accessToken'); 
       field.setAttribute("value", accessToken); 
       form.appendChild(field); 

       document.body.appendChild(form); 
       form.submit(); 

      } else if (response.status === 'not_authorized') { 
       // the user is logged in to Facebook, 
       // but has not authenticated your app 
      } else { 
       // the user isn't logged in to Facebook. 
      } 
     }); 
    }; 

    // Load the SDK Asynchronously 
    (function (d) { 
     var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; 
     if (d.getElementById(id)) { return; } 
     js = d.createElement('script'); js.id = id; js.async = true; 
     js.src = "//connect.facebook.net/en_US/all.js"; 
     ref.parentNode.insertBefore(js, ref); 
    } (document)); 
</script> 

<div class="fb-login-button" data-show-faces="true" data-width="400" data-max-rows="1"></div> 

About.cshtml

@{ 
    ViewBag.Title = "About Us"; 
} 

<h2>About</h2> 
<p> 
    @ViewBag.Message 
</p> 

您能否告訴我如何解決這個問題,以便顯示一個FB登錄按鈕,並且單擊它時會要求用戶執行FB身份驗證,然後將它們發回,然後我的應用程序將它們識別爲登錄用戶?

回答

3

至於登錄按鈕,如果您在訪問您的應用程序之前登錄Facebook,您將看到面部而不是登錄按鈕,獲取登錄按鈕的唯一方法是轉到Facebook。 com並做一個註銷或可能做一個Facebook註銷使用C#SDK。根據您的要求,這可能會或可能不是您想要的。如果這是你真正想要的,那麼在SDK文檔中有一些關於Re-Authentication的內容。

我調整了你的應用程序,通過刪除submit()並將其替換爲ajax文章,FacebookLogin操作已更改,並且我在About操作中添加了一些錯誤處理。您的原始應用程序可以正常工作,但如果您已登錄Facebook,它將自動重定向到About。

更新增加了一個不使用JavaScript的登錄鏈接,插入appid和appsecret並相應地調整端口號。這是從服務器端登錄樣本調整中發現here遠低於此代碼:)

注漂亮狀態值在服務器側流傳遞應該是你應該在ConnectResponse驗證(一unqiue值)方法,即產生FacebookLoginNoJs一個值,並確保它在ConnectResponse相同,以防止跨站請求forgery

HomeController.cs

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 
using Facebook; 

namespace FacebookTest.Controllers 
{ 
    public class HomeController : Controller 
    { 

     public ActionResult Index() 
     { 
      ViewBag.Message = "Welcome to ASP.NET MVC!"; 

      return View(); 
     } 

     public ActionResult About() 
     { 
      ViewBag.Message = "Please log in first"; 

      if (Session["AccessToken"] != null) 
      { 
       var accessToken = Session["AccessToken"].ToString(); 
       var client = new FacebookClient(accessToken); 

       try 
       { 
        dynamic result = client.Get("me", new { fields = "name,id" }); 
        string name = result.name; 
        string id = result.id; 

        ViewBag.Message = "Hello id: " + id + " aka " + name; 
       } 
       catch (FacebookOAuthException x) 
       { 

       } 
      } 

      return View(); 
     } 

     public void FacebookLogin(string uid, string accessToken) 
     { 
      var context = this.HttpContext; 
      context.Session["AccessToken"] = accessToken; 
     } 

     public ActionResult FacebookLoginNoJs() 
     { 
      return Redirect("https://www.facebook.com/dialog/oauth?client_id=MY-APPID-REMOVED&redirect_uri=http://localhost:45400/Home/ConnectResponse&state=secret"); 
     } 

     public ActionResult ConnectResponse(string state, string code, string error, string error_reason, string error_description, string access_token, string expires) 
     { 
      if (string.IsNullOrEmpty(error)) 
      { 
       try 
       { 
        var client = new FacebookClient(); 
        dynamic result = client.Post("oauth/access_token", 
               new 
               { 
                client_id = "MY-APPID-REMOVED", 
                client_secret = "MY-APP-SECRET-REMOVED", 
                redirect_uri = "http://localhost:45400/Home/ConnectResponse", 
                code = code 
               }); 

        Session["AccessToken"] = result.access_token; 

        if (result.ContainsKey("expires")) 
         Session["ExpiresIn"] = DateTime.Now.AddSeconds(result.expires); 

       } 
       catch 
       { 
        // handle errors 
       } 
      } 
      else 
      { 
       // Declined, check error 
      } 

      return RedirectToAction("Index"); 
     } 

    } 
} 

索引。CSHTML

@{ 
    ViewBag.Title = "Home Page"; 
} 

<h2>@ViewBag.Message</h2> 
<p> 
    To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. 
</p> 

<div id="fb-root"></div> 
<script> 
    window.fbAsyncInit = function() { 
     FB.init({ 
      //appId: 'YOUR_APP_ID', // App ID 
      appId: 'MY-APPID-REMOVED', // App ID 
      status: true, // check login status 
      cookie: true, // enable cookies to allow the server to access the session 
      xfbml: true // parse XFBML 
     }); 

     // Additional initialization code here 
     FB.Event.subscribe('auth.authResponseChange', function (response) { 
      if (response.status === 'connected') { 

       var uid = response.authResponse.userID; 
       var accessToken = response.authResponse.accessToken; 

       var url = '/Home/FacebookLogin'; 
       $.post(url, { uid: uid, accessToken: accessToken }, function (data) { 
       }); 

      } else if (response.status === 'not_authorized') { 
       // the user is logged in to Facebook, 
       // but has not authenticated your app 
      } else { 
       // the user isn't logged in to Facebook. 
      } 
     }); 
    }; 

    // Load the SDK Asynchronously 
    (function (d) { 
     var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0]; 
     if (d.getElementById(id)) { return; } 
     js = d.createElement('script'); js.id = id; js.async = true; 
     js.src = "//connect.facebook.net/en_US/all.js"; 
     ref.parentNode.insertBefore(js, ref); 
    } (document)); 
</script> 

<div class="fb-login-button" data-show-faces="true" data-width="400" data-max-rows="1"></div> 

@Html.ActionLink("The NoJs Login", "FacebookLoginNoJs", "Home") 

About.cshtml

@{ 
    ViewBag.Title = "About Us"; 
} 

<h2>About</h2> 
<p> 
     @ViewBag.Message 
</p> 
+0

刪除步驟1-3,因爲這不再是真實的,一定是固定的:)。添加了一個觸發服務器端登錄流的鏈接。 – 2012-07-16 08:28:30