访问Twitter的更多用户信息 [英] Access additional twitter user info

查看:176
本文介绍了访问Twitter的更多用户信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的Azure移动服务对用户进行授权,我现在试图获得来自供应商的其他用户信息。我有工作了所有的人,除了微博。为验证所有我使用类似这样的东西其他:

I'm using Azure Mobile Services to authorize users and am now trying to get additional user info from the providers. I have it working for all of them except Twitter. To authenticate for all the other I'm using something similar to this:

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));
}

我是否可以做这样的事情:

Would I be able to do something like this:

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=******************************"));
}

否则我会做一些完全不同的?

or would I have to do something completely different?

Woops,只是发现了类似的问题在这里:微博单一的URL请求

Woops, just found a similar question here: Twitter single url request

推荐答案

是的,这是可能的,但它比其他供应商更多的工作。

Yes, it is possible, but it's more work than for other providers.

这是code为API控制器(也许需要一些重构)

This is the code for your api controller (maybe needs some refactoring)

[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认证头:

Then you need this class to build a valid OAuth 1.0 authentication header:

(几乎所有的下列code从LinqToTwitter, HTTPS IST的://linqtotwitter.$c$ cplex.com

(almost all of the following code ist from 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();
    }
}

这篇关于访问Twitter的更多用户信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆