【问题标题】:Access additional twitter user info访问其他 Twitter 用户信息
【发布时间】:2015-04-22 04:17:36
【问题描述】:

我正在使用 Azure 移动服务对用户进行授权,现在正尝试从提供商处获取更多用户信息。除了 Twitter,我对他们所有人都有效。为了对所有其他人进行身份验证,我使用了类似的东西:

var identities = await user.GetIdentitiesAsync();
var result = new JObject();
var fb = identities.OfType<FacebookCredentials>().FirstOrDefault();
if (fb != null)
{
    var accessToken = fb.AccessToken;
    result.Add("facebook", await GetProviderInfo("https://graph.facebook.com/me?access_token=" + accessToken));
}

我能做这样的事情吗:

var tw = identities.OfType<TwitterCredentials>().FirstOrDefault();
if (tw != null)
{
    var accessToken = tw.AccessToken;
    var accessTokenSecret = tw.AccessTokenSecret;

    result.Add("twitter", await
    GetProviderInfo("https://api.twitter.com/1.1/account/verify_credentials.json?token=" + accessToken + "&token_secret=" + accessTokenSecret + "&consumer_key=***************" + "&consumer_secret=******************************"));
}

或者我必须做一些完全不同的事情吗?

糟糕,刚刚在这里发现了一个类似的问题:Twitter single url request

【问题讨论】:

    标签: c# azure twitter custom-controls azure-mobile-services


    【解决方案1】:

    是的,这是可能的,但它比其他提供商的工作量更大。

    这是您的 api 控制器的代码(可能需要一些重构)

    [HttpPost]
    [Route("current/identity")]
    public async Task<HttpResponseMessage> GetIdentityInfo()
    {
        var currentUser = User as ServiceUser;
    
        if (currentUser != null)
        {
            var identities = await currentUser.GetIdentitiesAsync();
    
            var googleCredentials = identities.OfType<GoogleCredentials>().FirstOrDefault();
    
            if (googleCredentials != null)
            {
                var infos = await GetGoolgeDetails(googleCredentials);
                return Request.CreateResponse(HttpStatusCode.OK, infos);
            }
    
            var facebookCredentials = identities.OfType<FacebookCredentials>().FirstOrDefault();
    
            if (facebookCredentials!= null)
            {
                var infos = await GetFacebookDetails(facebookCredentials);
                return Request.CreateResponse(HttpStatusCode.OK, infos);
            }
    
            var microsoftCredentials = identities.OfType<MicrosoftAccountCredentials>().FirstOrDefault();
    
            if (microsoftCredentials != null)
            {
                var infos = await GetMicrosoftDetails(microsoftCredentials);
                return Request.CreateResponse(HttpStatusCode.OK, infos);
            }
    
            var twitterCredentials = identities.OfType<TwitterCredentials>().FirstOrDefault();
    
            if (twitterCredentials != null)
            {
                var infos = await GetTwitterDetails(currentUser, twitterCredentials);
                return Request.CreateResponse(HttpStatusCode.OK, infos);
            }
        }
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    private async Task<JToken> GetTwitterDetails(ServiceUser currentUser, TwitterCredentials twitterCredentials)
    {
        var twitterId = currentUser.Id.Split(':').Last();
    
        var accessToken = twitterCredentials.AccessToken;
    
        string consumerKey = ConfigurationManager.AppSettings["MS_TwitterConsumerKey"];
        string consumerSecret = ConfigurationManager.AppSettings["MS_TwitterConsumerSecret"];
        // Add this setting manually on your Azure Mobile Services Management interface.
        // You will find the secret on your twitter app configuration
        string accessTokenSecret = ConfigurationManager.AppSettings["FG_TwitterAccessTokenSecret"];
    
        var parameters = new Dictionary<string, string>();
        parameters.Add("user_id", twitterId);
        parameters.Add("oauth_token", accessToken);
        parameters.Add("oauth_consumer_key", consumerKey);
    
        OAuth1 oauth = new OAuth1();
    
        string headerString = oauth.GetAuthorizationHeaderString(
            "GET", "https://api.twitter.com/1.1/users/show.json",
            parameters, consumerSecret, accessTokenSecret);
    
        var infos = await GetProviderInfo("https://api.twitter.com/1.1/users/show.json?user_id=" + twitterId, headerString);
        return infos;
    }
    
    private async Task<JToken> GetMicrosoftDetails(MicrosoftAccountCredentials microsoftCredentials)
    {
        var accessToken = microsoftCredentials.AccessToken;
        var infos = await GetProviderInfo("https://apis.live.net/v5.0/me/?method=GET&access_token=" + accessToken);
        return infos;
    }
    
    private async Task<JToken> GetFacebookDetails(FacebookCredentials facebookCredentials)
    {
        var accessToken = facebookCredentials.AccessToken;
        var infos = await GetProviderInfo("https://graph.facebook.com/me?access_token=" + accessToken);
        return infos;
    }
    
    private async Task<JToken> GetGoolgeDetails(GoogleCredentials googleCredentials)
    {
        var accessToken = googleCredentials.AccessToken;
        var infos = await GetProviderInfo("https://www.googleapis.com/oauth2/v3/userinfo?access_token=" + accessToken);
        return infos;
    }
    
    private async Task<JToken> GetProviderInfo(string url, string oauth1HeaderString = null)
    {
        using (var client = new HttpClient())
        {
    
            if (oauth1HeaderString != null)
            {
                client.DefaultRequestHeaders.Authorization = System.Net.Http.Headers.AuthenticationHeaderValue.Parse(oauth1HeaderString); 
            }
    
            var resp = await client.GetAsync(url).ConfigureAwait(false);
            resp.EnsureSuccessStatusCode();
            string rawInfo = await resp.Content.ReadAsStringAsync().ConfigureAwait(false);
            return JToken.Parse(rawInfo);
        }
    }
    

    那么你需要这个类来构建一个有效的 OAuth 1.0 认证头:

    (以下几乎所有代码都来自 LinqToTwitter,https://linqtotwitter.codeplex.com

    public class OAuth1
    {
        const string OAUTH_VERSION = "1.0";
        const string SIGNATURE_METHOD = "HMAC-SHA1";
        const long UNIX_EPOC_TICKS = 621355968000000000L;
    
        public string GetAuthorizationHeaderString(string method, string url, IDictionary<string, string> parameters, string consumerSecret, string accessTokenSecret)
        {
            string encodedAndSortedString = BuildEncodedSortedString(parameters);
            string signatureBaseString = BuildSignatureBaseString(method, url, encodedAndSortedString);
            string signingKey = BuildSigningKey(consumerSecret, accessTokenSecret);
            string signature = CalculateSignature(signingKey, signatureBaseString);
            string authorizationHeader = BuildAuthorizationHeaderString(encodedAndSortedString, signature);
    
            return authorizationHeader;
        }  
    
        internal void AddMissingOAuthParameters(IDictionary<string, string> parameters)
        {
            if (!parameters.ContainsKey("oauth_timestamp"))
                parameters.Add("oauth_timestamp", GetTimestamp());
    
            if (!parameters.ContainsKey("oauth_nonce"))
                parameters.Add("oauth_nonce", GenerateNonce());
    
            if (!parameters.ContainsKey("oauth_version"))
                parameters.Add("oauth_version", OAUTH_VERSION);
    
            if (!parameters.ContainsKey("oauth_signature_method"))
                parameters.Add("oauth_signature_method", SIGNATURE_METHOD);     
        }
    
        internal string BuildEncodedSortedString(IDictionary<string, string> parameters)
        {
            AddMissingOAuthParameters(parameters);
    
            return
                string.Join("&",
                    (from parm in parameters
                     orderby parm.Key
                     select parm.Key + "=" + PercentEncode(parameters[parm.Key]))
                    .ToArray());
        }
    
        internal virtual string BuildSignatureBaseString(string method, string url, string encodedStringParameters)
        {
            int paramsIndex = url.IndexOf('?');
    
            string urlWithoutParams = paramsIndex >= 0 ? url.Substring(0, paramsIndex) : url;
    
            return string.Join("&", new string[]
            {
                method.ToUpper(),
                PercentEncode(urlWithoutParams),
                PercentEncode(encodedStringParameters)
            });
        }
    
        internal virtual string BuildSigningKey(string consumerSecret, string accessTokenSecret)
        {
            return string.Format(
                CultureInfo.InvariantCulture, "{0}&{1}", 
                PercentEncode(consumerSecret),
                PercentEncode(accessTokenSecret));
        }
    
        internal virtual string CalculateSignature(string signingKey, string signatureBaseString)
        {
            byte[] key = Encoding.UTF8.GetBytes(signingKey);
            byte[] msg = Encoding.UTF8.GetBytes(signatureBaseString);
    
            KeyedHashAlgorithm hasher = new HMACSHA1();
            hasher.Key = key;
            byte[] hash = hasher.ComputeHash(msg);
    
            return Convert.ToBase64String(hash);
        }
    
        internal virtual string BuildAuthorizationHeaderString(string encodedAndSortedString, string signature)
        {
            string[] allParms = (encodedAndSortedString + "&oauth_signature=" + PercentEncode(signature)).Split('&');
            string allParmsString =
                string.Join(", ",
                    (from parm in allParms
                     let keyVal = parm.Split('=')
                     where parm.StartsWith("oauth") || parm.StartsWith("x_auth")
                     orderby keyVal[0]
                     select keyVal[0] + "=\"" + keyVal[1] + "\"")
                    .ToList());
            return "OAuth " + allParmsString;
        }
    
        internal virtual string GetTimestamp()
        {
            long ticksSinceUnixEpoc = DateTime.UtcNow.Ticks - UNIX_EPOC_TICKS;
            double secondsSinceUnixEpoc = new TimeSpan(ticksSinceUnixEpoc).TotalSeconds;
            return Math.Floor(secondsSinceUnixEpoc).ToString(CultureInfo.InvariantCulture);
        }
    
        internal virtual string GenerateNonce()
        {
            return new Random().Next(111111, 9999999).ToString(CultureInfo.InvariantCulture);
        }
    
        internal virtual string PercentEncode(string value)
        {
            const string ReservedChars = @"`!@#$^&*()+=,:;'?/|\[] ";
    
            var result = new StringBuilder();
    
            if (string.IsNullOrWhiteSpace(value))
                return string.Empty;
    
            var escapedValue = Uri.EscapeDataString(value);
    
            // Windows Phone doesn't escape all the ReservedChars properly, so we have to do it manually.
            foreach (char symbol in escapedValue)
            {
                if (ReservedChars.IndexOf(symbol) != -1)
                {
                    result.Append('%' + String.Format("{0:X2}", (int)symbol).ToUpper());
                }
                else
                {
                    result.Append(symbol);
                }
            }
    
            return result.ToString();
        }
    }
    

    【讨论】:

    • 那是勇敢的!它仍然有效吗?现在有更简单的方法吗?难怪它没有出现在样本中。
    猜你喜欢
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多