#c# #asp.net #oauth #dotnetopenauth
#c# #asp.net #oauth #dotnetopenauth
Вопрос:
Кто-нибудь успешно использовал DotNetOpenAuth для доступа к api Yelp версии v2 с использованием DotNetOpenAuth?
После изучения примеров и исходного кода, вот что я придумал:
public class YelpConnector
{
private static readonly string YelpConsumerKey = ConfigurationManager.AppSettings["YelpConsumerKey"];
private static readonly string YelpConsumerSecret = ConfigurationManager.AppSettings["YelpConsumerSecret"];
private static readonly string YelpToken = ConfigurationManager.AppSettings["YelpToken"];
private static readonly string YelpTokenSecret = ConfigurationManager.AppSettings["YelpTokenSecret"];
private static readonly InMemoryTokenManager tokenManager = new InMemoryTokenManager(YelpConsumerKey, YelpConsumerSecret, YelpToken, YelpTokenSecret);
private static readonly Uri YelpURLBase = new Uri("http://api.yelp.com/v2/");
private static readonly ServiceProviderDescription YelpServiceDescription = new ServiceProviderDescription {
RequestTokenEndpoint = null,
UserAuthorizationEndpoint = null,
AccessTokenEndpoint = null,
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
};
private static dynamic SearchBase(string queryString)
{
if (string.IsNullOrEmpty(queryString))
throw new ArgumentNullException();
var searchEndpoint = new MessageReceivingEndpoint(new Uri(YelpURLBase, "search?" queryString), HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest);
var consumer = new WebConsumer(YelpServiceDescription, tokenManager);
try
{
using (IncomingWebResponse response = consumer.PrepareAuthorizedRequestAndSend(searchEndpoint, YelpToken))
{
string rs = response.GetResponseReader().ReadToEnd();
dynamic js = SimpleJson.SimpleJson.DeserializeObject(rs);
return js;
}
}
catch (Exception e)
{
ErrorSignal.FromCurrentContext().Raise(e);
return null;
}
}
internal class InMemoryTokenManager : IConsumerTokenManager
{
private Dictionary<string, string> tokensAndSecrets = new Dictionary<string, string>();
public InMemoryTokenManager(string consumerKey, string consumerSecret, string token, string secret)
{
if (String.IsNullOrEmpty(consumerKey))
{
throw new ArgumentNullException("consumerKey");
}
this.tokensAndSecrets[token] = secret;
this.ConsumerKey = consumerKey;
this.ConsumerSecret = consumerSecret;
}
public string ConsumerKey { get; private set; }
public string ConsumerSecret { get; private set; }
public string GetTokenSecret(string token)
{
return this.tokensAndSecrets[token];
}
public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response)
{
this.tokensAndSecrets[response.Token] = response.TokenSecret;
}
public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret)
{
this.tokensAndSecrets.Remove(requestToken);
this.tokensAndSecrets[accessToken] = accessTokenSecret;
}
public TokenType GetTokenType(string token)
{
throw new NotImplementedException();
}
}
}
Если я передаю следующую строку запроса limit=5amp;category_filter=movietheaters,bars,cafe,museums,danceclubs,parksamp;ll=37.78364455,-122.464104
, я получаю исключение с сообщением «Сбой предварительного условия.: значение != null» и трассировку стека:
at System.Diagnostics.Contracts.__ContractsRuntime.Requires[TException](Boolean condition, String message, String conditionText)
at DotNetOpenAuth.Messaging.MessagingUtilities.EscapeUriDataStringRfc3986(String value)
at DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementBase.ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary)
at DotNetOpenAuth.OAuth.ChannelElements.HmacSha1SigningBindingElement.GetSignature(ITamperResistantOAuthMessage message)
at DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementBase.ProcessOutgoingMessage(IProtocolMessage message)
at DotNetOpenAuth.OAuth.ChannelElements.SigningBindingElementChain.ProcessOutgoingMessage(IProtocolMessage message)
at DotNetOpenAuth.Messaging.Channel.ProcessOutgoingMessage(IProtocolMessage message)
at DotNetOpenAuth.OAuth.ChannelElements.OAuthChannel.InitializeRequest(IDirectedProtocolMessage request)
at DotNetOpenAuth.OAuth.ConsumerBase.PrepareAuthorizedRequestAndSend(MessageReceivingEndpoint endpoint, String accessToken)
at MeetPpl.Helpers.SocialConnectors.YelpConnector.SearchBase(String queryString)
Есть предложения? Я на правильном пути?
Комментарии:
1. Я знаю, что я довольно сильно опоздал на эту вечеринку, но я написал библиотеку для этого: github.com/JustinBeckwith/YelpSharp . Это на NuGet. Я начал с Twitterizer, но он не обрабатывает некоторые расширенные параметры строки запроса для OAuth должным образом. Это
Ответ №1:
Я боролся с этой проблемой целый день, прежде чем отказаться от dotnetopenauth. Я нашел очень простой способ поиска в yelp с использованием библиотеки oauth http://www.twitterizer.net / . Просто скачайте облегченную версию twitterizer и используйте мой пример кода ниже.
Ссылка для скачивания естьhttp://www.twitterizer.net/files/Twitterizer2lite-2.3.2.zip
public static string search()
{
string yelpSearchURL = "http://api.yelp.com/v2/search?term=foodamp;location=San Francisco";
string yelpConsumerKey = "your key";
string yelpConsumerSecret = "your secret";
string yelpRequestToken = "your token";
string yelpRequestTokenSecret = "your token secret";
Twitterizer.OAuthTokens ot = new Twitterizer.OAuthTokens();
ot.AccessToken = yelpRequestToken;
ot.AccessTokenSecret = yelpRequestTokenSecret;
ot.ConsumerKey = yelpConsumerKey;
ot.ConsumerSecret = yelpConsumerSecret;
string formattedUri = String.Format(CultureInfo.InvariantCulture,
yelpSearchURL, "");
Uri url = new Uri(formattedUri);
Twitterizer.WebRequestBuilder wb = new Twitterizer.WebRequestBuilder(url, Twitterizer.HTTPVerb.GET, ot);
System.Net.HttpWebResponse wr = wb.ExecuteRequest();
StreamReader sr = new StreamReader(wr.GetResponseStream());
return sr.ReadToEnd();
}
Комментарии:
1. это не объясняет, откуда берется
AccessToken
, что радикально отличается в веб-приложении от настольного приложения…2. @Chirag Знаете ли вы, что существует еще меньшая библиотека Twitterizer, которая поддерживает только OAuth?
3. @JeffAtwood Вашему пользователю необходимо будет авторизовать ваше приложение. Результатом авторизации является токен доступа. В упрощенном виде это: 1) Получение токена доступа. 2) Перенаправить пользователя на URL авторизации. 3) Служба перенаправит пользователя на URL обратного вызова (на вашем сайте). 4) Получите токен доступа.
Ответ №2:
Вы можете использовать RestSharp api:https://github.com/JustinBeckwith/YelpSharp в сочетании с OAuthBase: http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs . В реализации YelpSharp измените метод класса Yelp.cs на makeRequest следующим образом:
protected string makeRequest(string area, string id, Dictionary<string, string> parameters)
{
// build the url with parameters
var url = area;
if (!String.IsNullOrEmpty(id)) url = "/" HttpUtility.UrlEncode(id);
if (parameters != null)
{
bool firstp = true;
string[] keys = parameters.Keys.ToArray();
foreach (string _key in keys)
{
if (firstp) url = "?";
else url = "amp;";
firstp = false;
//Double URL encode "amp;" to prevent restsharp from treating the second half of the string as a new parameter
parameters[_key] = parameters[_key].Replace("amp;", "&");
parameters[_key] = parameters[_key].Replace(" ", "+");
parameters[_key] = parameters[_key].Replace(" ", "+");
url = _key "=" parameters[_key]; //HttpUtility.UrlEncode(parameters[_key]);
}
}
var client = new RestClient(rootUri);
var request = new RestRequest(Method.GET);
OAuthBase oAuth = new OAuthBase();
string nonce = oAuth.GenerateNonce();
string timeStamp = oAuth.GenerateTimeStamp();
string normalizedUrl;
string normalizedRequestParameters;
string sig = oAuth.GenerateSignature(new Uri(string.Format("{0}/{1}", client.BaseUrl, url)),
options.ConsumerKey, options.ConsumerSecret,
options.AccessToken, options.AccessTokenSecret,
"GET", timeStamp, nonce, out normalizedUrl, out normalizedRequestParameters);
sig = HttpUtility.UrlEncode(sig);
request.Resource = string.Format(area);
if (parameters != null)
{
foreach (var p in parameters)
{
request.AddParameter(p.Key, p.Value);
}
}
request.AddParameter("oauth_consumer_key", options.ConsumerKey);
request.AddParameter("oauth_token", options.AccessToken);
request.AddParameter("oauth_nonce", nonce);
request.AddParameter("oauth_timestamp", timeStamp);
request.AddParameter("oauth_signature_method", "HMAC-SHA1");
request.AddParameter("oauth_version", "1.0");
request.AddParameter("oauth_signature", sig);
var response = client.Execute(request);
return response.Content;
}
Тестируйте следующим образом:
public void testYelp()
{
string _term = "food";
string _location = "San Francisco";
var o = Credentials.GetOptions();
var y = new Yelp(o);
var searchOptions = new SearchOptions();
searchOptions.GeneralOptions = new GeneralOptions()
{
term = _term
};
searchOptions.LocationOptions = new LocationOptions()
{
location = _location
};
var results = y.Search(searchOptions);
}