3

昨年末以来、LinkedIn がついに、現在ログオンしているユーザーの電子メール アドレスを取得できるようになったことを読んだ後、私はそうすることができませんでした。SOや他の場所で見つけることができるすべての投稿を読みましたが、コードが機能していると言える限りです。他のすべてのフィールドで問題なく返されます。

ただし、電子メール アドレス フィールドは常に空です。

これが私の LinkedInClient クラスです。

public class LinkedInClient2 : OAuthClient
{
    public static readonly ServiceProviderDescription LinkedInServiceDescription = new ServiceProviderDescription
    {
        AccessTokenEndpoint =
            new MessageReceivingEndpoint(
                "https://api.linkedin.com/uas/oauth/accessToken",
                HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
        RequestTokenEndpoint =
            new MessageReceivingEndpoint(
                "https://api.linkedin.com/uas/oauth/requestToken?scope=r_basicprofile+r_emailaddress",
                HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
        UserAuthorizationEndpoint =
            new MessageReceivingEndpoint(
                "https://www.linkedin.com/uas/oauth/authenticate",
                HttpDeliveryMethods.GetRequest | HttpDeliveryMethods.AuthorizationHeaderRequest),
        TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
        ProtocolVersion = ProtocolVersion.V10a
    };

    public LinkedInClient2(string consumerKey, string consumerSecret, IConsumerTokenManager tokenManager)
        : base("linkedIn", LinkedInServiceDescription, tokenManager)
    {
    }

    [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "We don't care if the request fails.")]
    protected override AuthenticationResult VerifyAuthenticationCore(AuthorizedTokenResponse response)
    {
        // See here for Field Selectors API http://developer.linkedin.com/docs/DOC-1014
        const string ProfileRequestUrl = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address,headline,industry,summary,picture-url)";
        string accessToken = response.AccessToken;
        var profileEndpoint = new MessageReceivingEndpoint(ProfileRequestUrl, HttpDeliveryMethods.GetRequest);
        HttpWebRequest request = this.WebWorker.PrepareAuthorizedRequest(profileEndpoint, accessToken);

        try
        {
            using (WebResponse profileResponse = request.GetResponse())
            {
                using (Stream responseStream = profileResponse.GetResponseStream())
                {
                    XDocument document = LoadXDocumentFromStream(responseStream);
                    string userId = document.Root.Element("id").Value;

                    // User Profile Fields - https://developer.linkedin.com/documents/profile-fields
                    string firstName = document.Root.Element("first-name").Value;
                    string lastName = document.Root.Element("last-name").Value;
                    string userName = document.Root.Element("email-address").Value; // <<<<<< ERROR - always empty

                    var extraData = new Dictionary<string, string>();
                    extraData.Add("accesstoken", accessToken);
                    extraData.Add("name", userName);
                    extraData.AddDataIfNotEmpty(document, "picture-url");
                    extraData.AddDataIfNotEmpty(document, "location");
                    extraData.AddDataIfNotEmpty(document, "headline");
                    extraData.AddDataIfNotEmpty(document, "summary");
                    extraData.AddDataIfNotEmpty(document, "industry");

                    return new AuthenticationResult(
                        isSuccessful: true, provider: this.ProviderName, providerUserId: userId, userName: userName, extraData: extraData);
                }
            }
        }
        catch (Exception exception)
        {
            return new AuthenticationResult(exception);
        }
    }

    internal static XDocument LoadXDocumentFromStream(Stream stream)
    {
        const int MaxChars = 0x10000; // 64k

        XmlReaderSettings settings = new XmlReaderSettings()
        {
            MaxCharactersInDocument = MaxChars
        };
        return XDocument.Load(XmlReader.Create(stream, settings));
    }
}

}

scope=r_emailaddress私は(私が持っている)に を追加することになっていることを理解していRequestTokenEndpointますが、フィドラーのトレースからは、そのエンドポイントがフェッチされていることさえわかりません。基本的に、それはAccessTokenEndpointおそらく私の問題に関係していると思われる のみを使用します。

これは、私の ASP.Net MVC4.5 コントローラーの外観とほぼ同じです。

    [AllowAnonymous]
    public virtual ActionResult LinkedIn(string returnUrl)
    {
        var tokenMgr = new RepoOAuthTokenManager(_iOtk, LinkedInAppKey, LinkedInAppSecret);
        var iacp = new LinkedInClient2(LinkedInAppKey, LinkedInAppSecret, tokenMgr); // if none specified, LinkedInClient uses the AuthenticationOnlyCookieOAuthTokenManager which doesn't work for APIs
        var ioadp = new MyOauthDataProvider();
        var oasm = new OpenAuthSecurityManager(this.HttpContext, iacp, ioadp);

        var redirectUri = Url.ActionFullyQualified(this.nameof(c => c.LinkedIn(null)), null, new RouteValueDictionary(new { returnUrl = returnUrl }));
        AuthenticationResult ar = oasm.VerifyAuthentication(redirectUri);
        if (ar.Error == null)
        {
            if (ar.IsSuccessful)
                DoSomethingResultingInRedirect(redirectUri); // OK
            else
                oasm.RequestAuthentication(redirectUri);
        }
        else
            ModelState.AddModelError("", ar.Error.Message);

        return View(this.nameof(c=>c.Login(null)));
    }//LinkedIn

DotNetOpenAuth の拡張メカニズムを完全に理解しているとは言えません。何かを誤解している可能性があるため、いくつかの指針をいただければ幸いです。

私はどこかでステップを逃していますか?

4

2 に答える 2

0

私は同様の問題を抱えていました..多分これはあなたに関連しています:

私のリクエストトークンコールは次のとおりです。

https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,member-url-resources,picture-url,location,public-profile-url,email-address )?フォーマット=json

しかし、json の応答は次のとおりです。

array(8) {
  ["emailAddress"]=>
  string(18) "email@email.com"
  ["firstName"]=>
  string(3) "Tim"
  ...

最初のケースでは email はemail-addressという名前で、2 番目のケースではemailAddressという名前であることに注意してください。

于 2013-11-06T09:18:52.833 に答える
0

これには2つの解決策がありますが、既存のコードを期待どおりに機能させる方法はまだわかりませんが、これが他の人の助けになることを願っています。

(1)既定のメンバー権限を簡単に追加できるようにするに移動し、 API 管理ページをクリックしました。

OAuth のデフォルト メンバー スコープ

ここで、デフォルトでリクエストするスコープを選択できます。という行に沿って書かれたボックス(現在は消えている)をクリックするまで機能しませんでし"[x] Make this permanent".email-address

(2)ここの情報から代わりに OAuth2 URL を使用してみましたが、うまくいくようでした。ここでOAuth2 クライアントの実装も見つけました。これは良いスタートのようです。長期的には、OAuth2 のアップグレード (仕様がより静的になると) により、全体的なマイレージが向上すると思われます。

今のところ、私は絶望の穴から抜け出していますが、他の回答は大歓迎です!

于 2013-07-29T14:26:40.717 に答える