DotNetOpenAuth CTP - Facebook的坏请求 [英] DotNetOpenAuth CTP - Facebook bad request
问题描述
我试图使用CTP通过OAuth 2.0与Facebook连接。
我可以将Facebook的初始请求提供给Facebook,但是回到我们的电话:
//其中null将成为HttpRequestInfo对象
client.ProcessUserAuthorization(null);
我得到:
远程服务器返回错误:(400)错误请求。
我的初始化并没有太多代码库;只将可选值设置为null(我们仍然在.NET 3.5)。任何线索都将不胜感激。
此外,我想这更是Andrew的一个问题。有没有一个论坛/博客的任何这些东西,或任何地方将定期更新?知道一些事情是非常好的:
- DotNetOpenAuth与OAuth 2.0的计划发布日期
- 无论.NET 4.0是否是先决条件
无论如何,任何建议都将是最受欢迎的。
在遇到此问题后,我写了自己的代码进行授权,并获得用户的详细信息。另一种方法是使用 Facebook C#SDK 。作为任何人想要做自己的人的首发,这里是我如何做到的。请注意,我没有研究错误情况。
首先, 客户端代码: I am trying to use the CTP to connect with Facebook over OAuth 2.0. I can get the initial request to Facebook working OK, but when it comes back and we call: I get: The remote server returned an error: (400) Bad Request. I haven't really done much with the initial codebase; merely set the optional values to null (we're still on .NET 3.5). Any clues would be much appreciated. Also, and i guess this is more of a question to Andrew specifically; is there a forum / blog for any of this stuff, or anywhere that will give regular updates? It would be great to know a few things: Anyway, any suggestions would be most welcome. After hitting this issue, I wrote my own code to authorize, and get the users details. Another approach would be to use Facebook C# SDK. As a starter for anyone else thinking about doing there own, here is how I did it. Please note I have not looked into error cases. Firstly, read facebooks doc on how it works (its rather simple!) I consume it like this: And the client code:
这篇关于DotNetOpenAuth CTP - Facebook的坏请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
private static readonly FacebookClient facebookClient = new FacebookClient();
public ActionResult LoginWithFacebook()
{
var result = facebookClient.Authorize();
if(result == FacebookAuthorisationResult.RequestingCode)
{
//客户端已经完成了一个Response.Redirect
return View();
} else if(result == FacebookAuthorisationResult.Authorized)
{
var user = facebookClient.GetCurrentUser();
}
返回重定向(/);
}
使用系统;
使用System.IO;
使用System.Net;
使用System.Runtime.Serialization;
使用System.Runtime.Serialization.Json;
使用System.Text;
使用System.Web;
命名空间Web.Services
{
公开枚举FacebookAuthorisationResult
{
被拒绝,
授权,
请求代码
}
public class FacebookClient
{
private const String SESSION_NAME_TOKEN =UserFacebookToken;
public FacebookClient()
{
TokenEndpoint = new Uri(https://graph.facebook.com/oauth/access_token);
AuthorizationEndpoint = new Uri(https://graph.facebook.com/oauth/authorize);
MeGraphEndpoint = new Uri(https://graph.facebook.com/me);
ClientIdentifier =xxxxxxxxxxxxxxxxxx;
Secret =xxxxxxxxxxxx;
LocalSubDomain =local.xxxxxxx.com;
}
public Uri TokenEndpoint {get;组; }
public Uri AuthorizationEndpoint {get;组; }
public Uri MeGraphEndpoint {get;组; }
public String Secret {get;组; }
public String ClientIdentifier {get;组; }
private String LocalSubDomain {get;组; }
public FacebookAuthorisationResult授权()
{
var errorReason = HttpContext.Current.Request.Params [error_reason];
var userDenied = errorReason!= null;
if(userDenied)
返回FacebookAuthorisationResult.Denied;
var verificationCode = HttpContext.Current.Request.Params [code];
var redirectUrl = GetResponseUrl(HttpContext.Current.Request.Url);
var needToGetVerificationCode = verificationCode == null;
if(needToGetVerificationCode)
{
var url = AuthorizationEndpoint +? +
client_id =+ ClientIdentifier +& +
redirect_uri =+ redirectUrl;
HttpContext.Current.Response.Redirect(url);
返回FacebookAuthorisationResult.RequestingCode;
}
var token = ExchangeCodeForToken(verificationCode,redirectUrl);
HttpContext.Current.Session [SESSION_NAME_TOKEN] =令牌;
返回FacebookAuthorisationResult.Authorized;
}
public Boolean IsCurrentUserAuthorized()
{
return HttpContext.Current.Session [SESSION_NAME_TOKEN]!= null;
}
public FacebookGraph GetCurrentUser()
{
var token = HttpContext.Current.Session [SESSION_NAME_TOKEN];
if(token == null)
返回null;
var url = MeGraphEndpoint +? +
access_token =+ token;
var request = WebRequest.CreateDefault(new Uri(url));
使用(var response = request.GetResponse())
{
using(var responseStream = response.GetResponseStream())
{
using(var responseReader = new StreamReader(responseStream))
{
var responseText = responseReader.ReadToEnd();
var user = FacebookGraph.Deserialize(responseText);
返回用户;
}
}
}
}
private String ExchangeCodeForToken(String code,Uri redirectUrl)
{
var url = TokenEndpoint +? +
client_id =+ ClientIdentifier +& +
redirect_uri =+ redirectUrl +& +
client_secret =+ Secret +& +
code =+ code;
var request = WebRequest.CreateDefault(new Uri(url));
使用(var response = request.GetResponse())
{
using(var responseStream = response.GetResponseStream())
{
using(var responseReader = new StreamReader(responseStream))
{
var responseText = responseReader.ReadToEnd();
var token = responseText.Replace(access_token =,);
返回令牌;
}
}
}
}
私人Uri GetResponseUrl(Uri url)
{
var urlAsString = url.ToString();
var doesUrlContainQuestionMark = urlAsString.Contains(?);
if(doesUrlContainQuestionMark)
{
//删除任何参数。显然,Facebook不支持状态:http://forum.developers.facebook.net/viewtopic.php?pid=255231
//如果不这样做,您会得到验证验证码错误
urlAsString = urlAsString.Substring(0,urlAsString.IndexOf(?));
}
var replaceLocalhostWithSubdomain = url.Host ==localhost;
if(!replaceLocalhostWithSubdomain)
返回新的Uri(urlAsString);
// Facebook不喜欢本地主机,您只能使用配置的网址。要解决这个问题,请登录到Facebook
//并设置您的站点域设置,即happycow.com。
//下一个编辑C:\Windows\System32\drivers\etc\hosts,添加行:
// 127.0.0.1 local.happycow.cow
//最后,将LocalSubDomain设置为local.happycow.cow
urlAsString = urlAsString.Replace(localhost,LocalSubDomain);
返回新的Uri(urlAsString);
}
}
[DataContract]
public class FacebookGraph
{
private static DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(FacebookGraph));
//注意:从int32更改为字符串,基于Antonin Jelinek建议溢出
[DataMember(Name =id)]
public string Id {get;组; }
[DataMember(Name =name)]
public string Name {get;组; }
[DataMember(Name =first_name)]
public string FirstName {get;组; }
[DataMember(Name =last_name)]
public string LastName {get;组; }
[DataMember(Name =link)]
public Uri Link {get;组; }
[DataMember(Name =birthday)]
public string Birthday {get;组;
public static FacebookGraph Deserialize(string json)
{
if(String.IsNullOrEmpty(json))
{
throw new ArgumentNullException(json );
}
返回反序列化(新的MemoryStream(Encoding.UTF8.GetBytes(json)));
}
public static FacebookGraph Deserialize(Stream jsonStream)
{
if(jsonStream == null)
{
throw new ArgumentNullException jsonStream);
}
return(FacebookGraph)jsonSerializer.ReadObject(jsonStream);
}
}
}
// Where null will become an HttpRequestInfo object
client.ProcessUserAuthorization(null);
private static readonly FacebookClient facebookClient = new FacebookClient();
public ActionResult LoginWithFacebook()
{
var result = facebookClient.Authorize();
if (result == FacebookAuthorisationResult.RequestingCode)
{
//The client will have already done a Response.Redirect
return View();
} else if (result == FacebookAuthorisationResult.Authorized)
{
var user = facebookClient.GetCurrentUser();
}
return Redirect("/");
}
using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
namespace Web.Services
{
public enum FacebookAuthorisationResult
{
Denied,
Authorized,
RequestingCode
}
public class FacebookClient
{
private const String SESSION_NAME_TOKEN = "UserFacebookToken";
public FacebookClient()
{
TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token");
AuthorizationEndpoint = new Uri("https://graph.facebook.com/oauth/authorize");
MeGraphEndpoint = new Uri("https://graph.facebook.com/me");
ClientIdentifier = "xxxxxxxxxxxxxxxxxx";
Secret = "xxxxxxxxxxxx";
LocalSubDomain = "local.xxxxxxx.com";
}
public Uri TokenEndpoint { get; set; }
public Uri AuthorizationEndpoint { get; set; }
public Uri MeGraphEndpoint { get; set; }
public String Secret { get; set; }
public String ClientIdentifier { get; set; }
private String LocalSubDomain { get; set; }
public FacebookAuthorisationResult Authorize()
{
var errorReason = HttpContext.Current.Request.Params["error_reason"];
var userDenied = errorReason != null;
if (userDenied)
return FacebookAuthorisationResult.Denied;
var verificationCode = HttpContext.Current.Request.Params["code"];
var redirectUrl = GetResponseUrl(HttpContext.Current.Request.Url);
var needToGetVerificationCode = verificationCode == null;
if (needToGetVerificationCode)
{
var url = AuthorizationEndpoint + "?" +
"client_id=" + ClientIdentifier + "&" +
"redirect_uri=" + redirectUrl;
HttpContext.Current.Response.Redirect(url);
return FacebookAuthorisationResult.RequestingCode;
}
var token = ExchangeCodeForToken(verificationCode, redirectUrl);
HttpContext.Current.Session[SESSION_NAME_TOKEN] = token;
return FacebookAuthorisationResult.Authorized;
}
public Boolean IsCurrentUserAuthorized()
{
return HttpContext.Current.Session[SESSION_NAME_TOKEN] != null;
}
public FacebookGraph GetCurrentUser()
{
var token = HttpContext.Current.Session[SESSION_NAME_TOKEN];
if (token == null)
return null;
var url = MeGraphEndpoint + "?" +
"access_token=" + token;
var request = WebRequest.CreateDefault(new Uri(url));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var responseReader = new StreamReader(responseStream))
{
var responseText = responseReader.ReadToEnd();
var user = FacebookGraph.Deserialize(responseText);
return user;
}
}
}
}
private String ExchangeCodeForToken(String code, Uri redirectUrl)
{
var url = TokenEndpoint + "?" +
"client_id=" + ClientIdentifier + "&" +
"redirect_uri=" + redirectUrl + "&" +
"client_secret=" + Secret + "&" +
"code=" + code;
var request = WebRequest.CreateDefault(new Uri(url));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
using (var responseReader = new StreamReader(responseStream))
{
var responseText = responseReader.ReadToEnd();
var token = responseText.Replace("access_token=", "");
return token;
}
}
}
}
private Uri GetResponseUrl(Uri url)
{
var urlAsString = url.ToString();
var doesUrlContainQuestionMark = urlAsString.Contains("?");
if (doesUrlContainQuestionMark)
{
// Remove any parameters. Apparently Facebook does not support state: http://forum.developers.facebook.net/viewtopic.php?pid=255231
// If you do not do this, you will get 'Error validating verification code'
urlAsString = urlAsString.Substring(0, urlAsString.IndexOf("?"));
}
var replaceLocalhostWithSubdomain = url.Host == "localhost";
if (!replaceLocalhostWithSubdomain)
return new Uri(urlAsString);
// Facebook does not like localhost, you can only use the configured url. To get around this, log into facebook
// and set your Site Domain setting, ie happycow.com.
// Next edit C:\Windows\System32\drivers\etc\hosts, adding the line:
// 127.0.0.1 local.happycow.cow
// And lastly, set LocalSubDomain to local.happycow.cow
urlAsString = urlAsString.Replace("localhost", LocalSubDomain);
return new Uri(urlAsString);
}
}
[DataContract]
public class FacebookGraph
{
private static DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(FacebookGraph));
// Note: Changed from int32 to string based on Antonin Jelinek advise of an overflow
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "first_name")]
public string FirstName { get; set; }
[DataMember(Name = "last_name")]
public string LastName { get; set; }
[DataMember(Name = "link")]
public Uri Link { get; set; }
[DataMember(Name = "birthday")]
public string Birthday { get; set; }
public static FacebookGraph Deserialize(string json)
{
if (String.IsNullOrEmpty(json))
{
throw new ArgumentNullException("json");
}
return Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(json)));
}
public static FacebookGraph Deserialize(Stream jsonStream)
{
if (jsonStream == null)
{
throw new ArgumentNullException("jsonStream");
}
return (FacebookGraph)jsonSerializer.ReadObject(jsonStream);
}
}
}