将 facebooksdk 与 Identity 2.0 集成
Integrate facebooksdk with Identity 2.0
我有一个 MVC5 应用程序,并且已经弄清楚了如何最初使用 Identity 2.0 通过 facebook 进行身份验证。除了添加email到scope之外,基本都是默认的:
var options = new FacebookAuthenticationOptions()
{
AppId = "##################",
AppSecret = "######################"
};
options.Scope.Add("email");
app.UseFacebookAuthentication(options);
在我的应用程序的另一个部分,用户可能需要升级 facebook 令牌才能发布到他们的墙上(我希望只添加 options.Scope.Add("publish_stream");
)。当我将上面的代码剪掉并将其放在 catch
此处 (the code below is referenced here at facebooksdk.net):
try {
var client = new FacebookClient("my_access_token");
dynamic result = client.Get("me/friends");
} catch (FacebookOAuthException) {
// Our access token is invalid or expired
// Here we need to do something to handle this.
}
它不喜欢初学者的 app.
,我不知道用什么来代替它。解决这个问题的正确方法是什么?我知道 facebooksdk.net 上有关于他们所做的任何令牌请求的示例,但我希望将其与 Identity 2.0 集成。或者这有关系吗?我不确定我是否正确理解身份过程,也不真正熟悉 facebook 身份验证,所以希望有人能理解我正在尝试做的事情并指导我?我的猜测是,我只需要将我在登录 SQL table 中的 facebook 令牌传递给 facebook,它会要求用户使用提升的权限重新进行身份验证?如果令牌最初不存在于登录 table 中,该过程会将其添加到那里。
郑重声明,我意识到我最初可以请求权限(当用户首次使用 Facebook 登录我们的网站时),但我们一开始尽量不吓跑更精明的用户。所以,这个想法是当他们点击发布他们的文章时,如果他们选择发布到 facebook,它将第一次请求升级令牌,然后希望永远不会再(永远不会的部分可能是一厢情愿的想法)。
谢谢。
Facebook 可能会令人困惑。您需要的令牌取决于您要实现的操作。例如,
- 您使用您的应用程序令牌请求具有特定的用户令牌
权限。
- 然后您将使用该 USER
代表用户访问 facebook api 的令牌。
在您发布的代码中,您似乎拥有发送给 Facebook 的访问令牌,作为授予您的应用程序的访问令牌……而不是给定用户的访问令牌。在成功授予给定用户访问权限后,您需要捕获(并存储)Facebook 提供给您的用户访问令牌。更多关于这里:
https://developers.facebook.com/docs/facebook-login/access-tokens
这是一些使用 Identity 框架的示例代码(在 startup_auth.cs 中使用)。它捕获访问令牌并为给定用户保留它(作为声明)。稍后可以读取访问令牌,以便用户在任何给定时间访问 facebook api。
// Facebook integration
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
AppId = ConfigurationManager.AppSettings["Facebook.appID"],
AppSecret = ConfigurationManager.AppSettings["Facebook.appSecret"],
Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
// STORE THE USER ACCESS TOKEN GIVEN TO US BY FACEBOOK FOR THIS USER
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook"));
foreach (var x in context.User)
{
var claimType = string.Format("urn:facebook:{0}", x.Key);
string claimValue = x.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new Claim(claimType, claimValue, XmlSchemaString, "Facebook"));
}
return Task.FromResult(0);
}
}
};
facebookOptions.Scope.Add("email");
facebookOptions.Scope.Add("publish_actions");
app.UseFacebookAuthentication(facebookOptions);
现在要为用户检索访问令牌,您可以像这样检索它(在来自 facebook 的回调 function/url 中):
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
var accessToken = loginInfo.ExternalIdentity.Claims
.Where(c => c.Type.EndsWith("facebook:access_token"))
.FirstOrDefault();
....
}
我有一个 MVC5 应用程序,并且已经弄清楚了如何最初使用 Identity 2.0 通过 facebook 进行身份验证。除了添加email到scope之外,基本都是默认的:
var options = new FacebookAuthenticationOptions()
{
AppId = "##################",
AppSecret = "######################"
};
options.Scope.Add("email");
app.UseFacebookAuthentication(options);
在我的应用程序的另一个部分,用户可能需要升级 facebook 令牌才能发布到他们的墙上(我希望只添加 options.Scope.Add("publish_stream");
)。当我将上面的代码剪掉并将其放在 catch
此处 (the code below is referenced here at facebooksdk.net):
try {
var client = new FacebookClient("my_access_token");
dynamic result = client.Get("me/friends");
} catch (FacebookOAuthException) {
// Our access token is invalid or expired
// Here we need to do something to handle this.
}
它不喜欢初学者的 app.
,我不知道用什么来代替它。解决这个问题的正确方法是什么?我知道 facebooksdk.net 上有关于他们所做的任何令牌请求的示例,但我希望将其与 Identity 2.0 集成。或者这有关系吗?我不确定我是否正确理解身份过程,也不真正熟悉 facebook 身份验证,所以希望有人能理解我正在尝试做的事情并指导我?我的猜测是,我只需要将我在登录 SQL table 中的 facebook 令牌传递给 facebook,它会要求用户使用提升的权限重新进行身份验证?如果令牌最初不存在于登录 table 中,该过程会将其添加到那里。
郑重声明,我意识到我最初可以请求权限(当用户首次使用 Facebook 登录我们的网站时),但我们一开始尽量不吓跑更精明的用户。所以,这个想法是当他们点击发布他们的文章时,如果他们选择发布到 facebook,它将第一次请求升级令牌,然后希望永远不会再(永远不会的部分可能是一厢情愿的想法)。
谢谢。
Facebook 可能会令人困惑。您需要的令牌取决于您要实现的操作。例如,
- 您使用您的应用程序令牌请求具有特定的用户令牌 权限。
- 然后您将使用该 USER 代表用户访问 facebook api 的令牌。
在您发布的代码中,您似乎拥有发送给 Facebook 的访问令牌,作为授予您的应用程序的访问令牌……而不是给定用户的访问令牌。在成功授予给定用户访问权限后,您需要捕获(并存储)Facebook 提供给您的用户访问令牌。更多关于这里: https://developers.facebook.com/docs/facebook-login/access-tokens
这是一些使用 Identity 框架的示例代码(在 startup_auth.cs 中使用)。它捕获访问令牌并为给定用户保留它(作为声明)。稍后可以读取访问令牌,以便用户在任何给定时间访问 facebook api。
// Facebook integration
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
AppId = ConfigurationManager.AppSettings["Facebook.appID"],
AppSecret = ConfigurationManager.AppSettings["Facebook.appSecret"],
Provider = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
// STORE THE USER ACCESS TOKEN GIVEN TO US BY FACEBOOK FOR THIS USER
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, XmlSchemaString, "Facebook"));
foreach (var x in context.User)
{
var claimType = string.Format("urn:facebook:{0}", x.Key);
string claimValue = x.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new Claim(claimType, claimValue, XmlSchemaString, "Facebook"));
}
return Task.FromResult(0);
}
}
};
facebookOptions.Scope.Add("email");
facebookOptions.Scope.Add("publish_actions");
app.UseFacebookAuthentication(facebookOptions);
现在要为用户检索访问令牌,您可以像这样检索它(在来自 facebook 的回调 function/url 中):
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
var accessToken = loginInfo.ExternalIdentity.Claims
.Where(c => c.Type.EndsWith("facebook:access_token"))
.FirstOrDefault();
....
}