2016-03-31 14 views
11

Sprawdziłem kilka powiązanych pytań, aby znaleźć odpowiedź na moje pytanie, ale wszystko bez skutku. To pytanie Can we get email ID from Twitter oauth API? got me miarę coraz wsparcie Twitter, aby umożliwić zgodę na mojej aplikacji poniżej: Additional permissions Korzystanie z tej doc jako przewodnik i oznakowanych odpowiedzieć za code (modyfikując trochę)Pobierz e-mail użytkownika z Twitter API dla zewnętrznego logowania Autentication ASP.NET MVC C#

var resource_url = "https://api.twitter.com/1.1/account/verify_credentials.json"; 
var postBody = "include_email=true";// 
resource_url += "?" + postBody; 

do wygeneruj podpis i zgłoś prośbę o podanie danych użytkownika ze strony twitter w 401 Unauthorized w mojej aplikacji MVC.

Jednak, gdy używam narzędzia generatora podpisów twitter do generowania nagłówka autoryzacji i używania skrzypka do wysłania żądania GET do https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true, otrzymuję wiadomość e-mail tylko raz i muszę ponownie wygenerować klucze do aplikacji w witrynie Twitter, aby uzyskać je ponownie .

Czy jest dokumentacja dotycząca sposobu wygenerowania ważnego podpisu i złożenia ważnego wniosku o odzyskanie wiadomości e-mail użytkownika Twitter za pośrednictwem .NET TwitterAuthentication?

Odpowiedz

15

Po prawie łysy od wyciągania z głowy wszystkich włosów, w końcu udało mi się. Dowiedziałem się, że ciąg znaków Signature nieznacznie różni się od tego, który został wygenerowany przy pomocy mojego kodu. Po drobnych poprawkach udało mi się wygenerować prawidłowy łańcuch bazowy sygnatur.

W Startup.cs, dodałem access_token i access_secret jako roszczenia. Nie używałem tego znalezionego na mojej aplikacji, ponieważ użytkownicy muszą powołać nowy, jak próbują się zalogować lub zarejestrować:

var twitterOptions = new Microsoft.Owin.Security.Twitter.TwitterAuthenticationOptions() 
{ 
    ConsumerKey = ConfigurationManager.AppSettings["consumer_key"], 
    ConsumerSecret = ConfigurationManager.AppSettings["consumer_secret"], 
    Provider = new Microsoft.Owin.Security.Twitter.TwitterAuthenticationProvider 
    { 
     OnAuthenticated = (context) => 
     { 
     context.Identity.AddClaim(new System.Security.Claims.Claim("urn:twitter:access_token", context.AccessToken)); 
     context.Identity.AddClaim(new System.Security.Claims.Claim("urn:twitter:access_secret", context.AccessTokenSecret)); 
     return Task.FromResult(0); 
     } 
    }, 
    BackchannelCertificateValidator = new Microsoft.Owin.Security.CertificateSubjectKeyIdentifierValidator(new[] 
    { 
     "A5EF0B11CEC04103A34A659048B21CE0572D7D47", // VeriSign Class 3 Secure Server CA - G2 
     "0D445C165344C1827E1D20AB25F40163D8BE79A5", // VeriSign Class 3 Secure Server CA - G3 
     "7FD365A7C2DDECBBF03009F34339FA02AF333133", // VeriSign Class 3 Public Primary Certification Authority - G5 
     "39A55D933676616E73A761DFA16A7E59CDE66FAD", // Symantec Class 3 Secure Server CA - G4 
     "‎add53f6680fe66e383cbac3e60922e3b4c412bed", // Symantec Class 3 EV SSL CA - G3 
     "4eb6d578499b1ccf5f581ead56be3d9b6744a5e5", // VeriSign Class 3 Primary CA - G5 
     "5168FF90AF0207753CCCD9656462A212B859723B", // DigiCert SHA2 High Assurance Server C‎A 
     "B13EC36903F8BF4701D498261A0802EF63642BC3" // DigiCert High Assurance EV Root CA 
    }), 
    CallbackPath = new PathString("/twitter/account/ExternalLoginCallback") 
}; 

app.UseTwitterAuthentication(twitterOptions); 

i wreszcie w moim kontrolera, po prostu zadzwonił do mojego klasy pomocnika, aby uzyskać nazwę i e-mail z Twitter

if (loginInfo.Login.LoginProvider.ToLower() == "twitter") 
    { 
     string access_token = loginInfo.ExternalIdentity.Claims.Where(x => x.Type == "urn:twitter:access_token").Select(x => x.Value).FirstOrDefault(); 
     string access_secret = loginInfo.ExternalIdentity.Claims.Where(x => x.Type == "urn:twitter:access_secret").Select(x => x.Value).FirstOrDefault(); 
     TwitterDto response = MyHelper.TwitterLogin(access_token, access_secret, ConfigurationManager.AppSettings["consumer_key"], ConfigurationManager.AppSettings["consumer_secret"]); 
     // by now response.email should possess the email value you need 
    } 

Helper klasa metoda:

To była sekcja i manipulowane w celu dokonania ważny wniosek:

basestring = string.Concat ("GET &" Uri.EscapeDataString (resource_url) + "&" + Uri.EscapeDataString (request_query) "% 26" Uri.EscapeDataString (basestring));

public static TwitterDto TwitterLogin(string oauth_token, string oauth_token_secret, string oauth_consumer_key, string oauth_consumer_secret) 
     { 
      // oauth implementation details 
      var oauth_version = "1.0"; 
      var oauth_signature_method = "HMAC-SHA1"; 

      // unique request details 
      var oauth_nonce = Convert.ToBase64String(
       new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString())); 
      var timeSpan = DateTime.UtcNow 
       - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 
      var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString(); 

      var resource_url = "https://api.twitter.com/1.1/account/verify_credentials.json"; 
      var request_query = "include_email=true"; 
      // create oauth signature 
      var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" + 
          "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}"; 

      var baseString = string.Format(baseFormat, 
             oauth_consumer_key, 
             oauth_nonce, 
             oauth_signature_method, 
             oauth_timestamp, 
             oauth_token, 
             oauth_version 
             ); 

      baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url) + "&" + Uri.EscapeDataString(request_query), "%26", Uri.EscapeDataString(baseString)); 

      var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret), 
            "&", Uri.EscapeDataString(oauth_token_secret)); 

      string oauth_signature; 
      using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey))) 
      { 
       oauth_signature = Convert.ToBase64String(
        hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString))); 
      } 

      // create the request header 
      var headerFormat = "OAuth oauth_consumer_key=\"{0}\", oauth_nonce=\"{1}\", oauth_signature=\"{2}\", oauth_signature_method=\"{3}\", oauth_timestamp=\"{4}\", oauth_token=\"{5}\", oauth_version=\"{6}\""; 

      var authHeader = string.Format(headerFormat, 
            Uri.EscapeDataString(oauth_consumer_key), 
            Uri.EscapeDataString(oauth_nonce), 
            Uri.EscapeDataString(oauth_signature), 
            Uri.EscapeDataString(oauth_signature_method), 
            Uri.EscapeDataString(oauth_timestamp), 
            Uri.EscapeDataString(oauth_token), 
            Uri.EscapeDataString(oauth_version) 
          ); 


      // make the request 

      ServicePointManager.Expect100Continue = false; 
      resource_url += "?include_email=true"; 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url); 
      request.Headers.Add("Authorization", authHeader); 
      request.Method = "GET"; 

      WebResponse response = request.GetResponse(); 
      return JsonConvert.DeserializeObject<TwitterDto>(new StreamReader(response.GetResponseStream()).ReadToEnd()); 
     } 
    } 

    public class TwitterDto 
    { 
     public string name { get; set; } 
     public string email { get; set; } 
    } 

To wszystko czego potrzebujesz, aby e-mail użytkownika Twittera. Mam nadzieję, że pomoże komuś walczyć z tym. Należy pamiętać, że kroki wymienione w pytaniu są również bardzo ważne.

+2

to był świetny wysiłek i dziękuję za udostępnienie – Webruster

+0

Cześć Oluwafemi, czy ten kod nadal działa dla Ciebie? Mam do czynienia z tym problemem, gdzie dostaję 401 za każdym razem, gdy próbuję poprosić o e-mail https://api.twitter.com/1.1/account/verify_credentials.json .. Mam pozwolenie od Twittera i kiedy używam generatora Signature z Twittera (https://dev.twitter.com/oauth/tools/signature-generator/[APPID]) wszystko działa dobrze. Nagłówek autoryzacji utworzony przez twój kod wygląda bardzo podobnie, ale nie działa dla mnie. Czy może masz działający przykład? –

+0

@Guido Powyższa metoda pomocnicza używana tak jak powinna. Obecnie pracuje nad wszystkimi moimi witrynami na żywo. – Oluwafemi

0

Musisz zmienić swój kod, aby połączyć się z kontem GET/metodą weryfikacji_weryfikacji po zalogowaniu użytkownika za pomocą Twittera. Ważne jest, aby ustawić parametr include_email na true. Gdy ta opcja jest ustawiona na true, e-mail zostanie zwrócony w obiektach użytkownika jako ciąg znaków. Używam tej biblioteki https://www.nuget.org/packages/linqtotwitter tak, że nie trzeba pisać kod do obsługi API Twittera prosi

var twitterCtx = new TwitterContext(authTwitter); 
var verifyResponse = await 
    (from acct in twitterCtx.Account 
    where (acct.Type == AccountType.VerifyCredentials) && (acct.IncludeEmail == true) 
    select acct) 
    .SingleOrDefaultAsync(); 

zobaczyć, jak mam zrobić to tutaj http://www.bigbrainintelligence.com/Post/get-users-email-address-from-twitter-oauth-ap

jest to łatwe i czyste rozwiązanie

Powiązane problemy