如何从 OAuthWebSecurity 获取 ExtraData? [英] How can I get ExtraData from OAuthWebSecurity?

查看:68
本文介绍了如何从 OAuthWebSecurity 获取 ExtraData?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(MVC 4)

AuthConfig.cs 中的定义;

AuthConfig.cs in definition;

OAuthWebSecurity.RegisterFacebookClient(
  appId: "21703538509...",
  appSecret: "28cbbc965e8ff6c9dc57cac9e323..."
);

ExternalLoginCallback 函数中,OAuthWebSecurity.VerifyAuthentication 返回的结果是(name,link,gender).但是,我需要电子邮件地址.如何从 Facebook 获取电子邮件地址?

ExternalLoginCallback function in, OAuthWebSecurity.VerifyAuthentication returned results are (name,link,gender). However, I need the email address. How can I get the email address from Facebook?

推荐答案

要获得电子邮件访问权限,您需要编写自定义 facebook 提供程序.

To get email access you need to write a custom facebook provider.

下载DotNetOpenAuth.AspNet.Clients.FacebookClient 并添加{ "scope", "email, read_stream" },

public sealed class CustomFacebookClient : OAuth2Client
{
    #region Constants and Fields

    /// <summary>
    /// The authorization endpoint.
    /// </summary>
    private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth";

    /// <summary>
    /// The token endpoint.
    /// </summary>
    private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token";

    /// <summary>
    /// The _app id.
    /// </summary>
    private readonly string appId;

    /// <summary>
    /// The _app secret.
    /// </summary>
    private readonly string appSecret;

    #endregion

    #region Constructors and Destructors

    /// <summary>
    /// Initializes a new instance of the <see cref="FacebookClient"/> class.
    /// </summary>
    /// <param name="appId">
    /// The app id.
    /// </param>
    /// <param name="appSecret">
    /// The app secret.
    /// </param>
    public CustomFacebookClient(string appId, string appSecret)
        : base("facebook")
    {
        Requires.NotNullOrEmpty(appId, "appId");
        Requires.NotNullOrEmpty(appSecret, "appSecret");

        this.appId = appId;
        this.appSecret = appSecret;
    }

    #endregion

    #region Methods

    /// <summary>
    /// The get service login url.
    /// </summary>
    /// <param name="returnUrl">
    /// The return url.
    /// </param>
    /// <returns>An absolute URI.</returns>
    protected override Uri GetServiceLoginUrl(Uri returnUrl)
    {
        // Note: Facebook doesn't like us to url-encode the redirect_uri value
        var builder = new UriBuilder(AuthorizationEndpoint);
        builder.AppendQueryArgs(
            new Dictionary<string, string> {
                { "client_id", this.appId },
                { "scope", "email, read_stream" },
                { "redirect_uri", returnUrl.AbsoluteUri }
            });
        return builder.Uri;
    }

    /// <summary>
    /// The get user data.
    /// </summary>
    /// <param name="accessToken">
    /// The access token.
    /// </param>
    /// <returns>A dictionary of profile data.</returns>
    protected override IDictionary<string, string> GetUserData(string accessToken)
    {
        FacebookGraphData graphData;
        var request =
            WebRequest.Create(
                "https://graph.facebook.com/me?access_token=" + FacebookClientHelper.EscapeUriDataStringRfc3986(accessToken));
        using (var response = request.GetResponse())
        {
            using (var responseStream = response.GetResponseStream())
            {


                graphData = FacebookClientHelper.Deserialize<FacebookGraphData>(responseStream);
            }
        }

        // this dictionary must contains 
        var userData = new Dictionary<string, string>();
        userData.AddItemIfNotEmpty("id", graphData.Id);
        userData.AddItemIfNotEmpty("username", graphData.Email);
        userData.AddItemIfNotEmpty("name", graphData.Name);
        userData.AddItemIfNotEmpty("link", graphData.Link == null ? null : graphData.Link.AbsoluteUri);
        userData.AddItemIfNotEmpty("gender", graphData.Gender);
        userData.AddItemIfNotEmpty("birthday", graphData.Birthday);
        userData.AddItemIfNotEmpty("email", graphData.Email);
        return userData;
    }

    /// <summary>
    /// Obtains an access token given an authorization code and callback URL.
    /// </summary>
    /// <param name="returnUrl">
    /// The return url.
    /// </param>
    /// <param name="authorizationCode">
    /// The authorization code.
    /// </param>
    /// <returns>
    /// The access token.
    /// </returns>
    protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
    {
        // Note: Facebook doesn't like us to url-encode the redirect_uri value
        var builder = new UriBuilder(TokenEndpoint);
        builder.AppendQueryArgs(
            new Dictionary<string, string> {
                { "client_id", this.appId },
                { "redirect_uri", NormalizeHexEncoding(returnUrl.AbsoluteUri) },
                { "client_secret", this.appSecret },
                { "code", authorizationCode },
            });

        using (WebClient client = new WebClient())
        {
            string data = client.DownloadString(builder.Uri);
            if (string.IsNullOrEmpty(data))
            {
                return null;
            }

            var parsedQueryString = HttpUtility.ParseQueryString(data);
            return parsedQueryString["access_token"];
        }
    }

    /// <summary>
    /// Converts any % encoded values in the URL to uppercase.
    /// </summary>
    /// <param name="url">The URL string to normalize</param>
    /// <returns>The normalized url</returns>
    /// <example>NormalizeHexEncoding("Login.aspx?ReturnUrl=%2fAccount%2fManage.aspx") returns "Login.aspx?ReturnUrl=%2FAccount%2FManage.aspx"</example>
    /// <remarks>
    /// There is an issue in Facebook whereby it will rejects the redirect_uri value if
    /// the url contains lowercase % encoded values.
    /// </remarks>
    private static string NormalizeHexEncoding(string url)
    {
        var chars = url.ToCharArray();
        for (int i = 0; i < chars.Length - 2; i++)
        {
            if (chars[i] == '%')
            {
                chars[i + 1] = char.ToUpperInvariant(chars[i + 1]);
                chars[i + 2] = char.ToUpperInvariant(chars[i + 2]);
                i += 2;
            }
        }
        return new string(chars);
    }

    #endregion

}

此外,人们可能认为这可行:

Also, one could think this could work:

var parameters = new Dictionary<string, object>();
parameters["scope"] = "email";

OAuthWebSecurity.RegisterFacebookClient(appId:  "appId", appSecret: "appSecret",
"facebook, parameters);

这不起作用.它为您的提供者提供了额外的数据,您可以在视图中展示您的提供者时使用这些数据.

This doesn't work. It gives extra data for your providers, which you can use when you present your providers in views.

<img src="@provder.ExtraData["icon"]"/>

这篇关于如何从 OAuthWebSecurity 获取 ExtraData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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