注册外部登录网站 API
Register External Login Web API
我不明白为什么他们没有明确的教程或指南,所以我希望我的问题能在这里得到解答。
因此,尝试通过网络从 facebook 或 google 注册用户 Api。
问题是,在 RegisterExternal
方法中,这一行:
var info = await Authentication.GetExternalLoginInfoAsync();
它returns为null,因此返回一个BadRequest()
到目前为止我得到了什么:
在 Startup.Auth.cs
中,我已经知道了 ID 和秘密,请注意,我也尝试过使用 Microsoft.Owin.Security.Facebook
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
AppId = "103596246642104",
AppSecret = "1c9c8f696e47bbc661702821c5a8ae75",
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
return Task.FromResult(0);
}
},
};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "328779658984-t9d67rh2nr681bahfusan0m5vuqeck13.apps.googleusercontent.com",
ClientSecret = "ZYcNHxBqH56Y0J2-tYowp9q0",
CallbackPath = new PathString("/api/Account/ManageInfo")
});
facebookOptions 来源:this post
那个额外的 facebookOptions 没有解决问题。
我能够从 Google 和 Facebook 检索到 access_token。我还可以使用 access_token 到 api/Account/UserInfo
进行身份验证
GET http://localhost:4856/api/Account/UserInfo
in the header:
Authorization: Bearer R9BTVhI0...
其中returns:
{"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}
我注意到他们的一个问题是 returns 我的名字作为电子邮件,而不是实际的电子邮件地址。
现在我想为我的数据库注册一个新用户的外部登录,我这样调用 POST:
POST http://localhost:4856/api/Account/RegisterExternal
[header]
authorization: bearer 6xcJoutY...
Content-Type: application/json
[body]
{"Email":"...@hotmail.com"}
来源:this post
现在这个 returns 这个代码片段上的 BadRequest,在 RegisterExternal():
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//AuthenticationManger?
var info = await Authentication.GetExternalLoginInfoAsync();
if (info == null)
{
return InternalServerError();
}
在调试中,ExternalLoginConfirmationViewModel
确实包含我的电子邮件地址。
我做错了什么?我是否必须向 Startup.cs
添加一些内容?在 Startup.Auth.cs
中我还需要做些什么吗?我是否错误地调用了 RegisterExternal
?在 MVC 中如此顺利,为什么在 Web 中不行 API?
阿苏看了this answer from this question,但是没看懂怎么实现。
这种方法不太实用,因为你正在开发一个 API,很可能会用于应用程序,你最好的方法是处理 API 消费者使用 facebook 的登录,然后让他们向您发送一个 Facebook 身份验证令牌。
基本上我正在尝试这样做:
- 为 facebook 创建外部登录 link。
- 将用户发送到那个 link 将把他们带到 facebook 登录页面。
- 登录后 facebook 将重定向到 api。
- 用户将被注册,但是正在使用 API 的 app/website 是如何知道的?
你要做的是:
- API 消费者创建自己的 facebook 登录方法(对于通过 SDK 的应用程序)
- API 消费者将向 API 发送一个 facebook 令牌到 register/login。
- API 将使用 facebook 图表端点检查令牌。
- 成功后,API 将 return 一个不记名令牌,供 API 进行进一步的身份验证请求。
因此,作为 API 开发人员,您将像这样验证令牌:
var verifyTokenEndPoint = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", accessToken, appToken);
然后获取userId
var client = new HttpClient();
var uri = new Uri(verifyTokenEndPoint);
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
dynamic jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(content);
string user_id = jObj["data"]["user_id"];
string app_id = jObj["data"]["app_id"];
}
最终您会像这样创建或找到一个用户:
IdentityUser user = await _userManager.FindAsync(new UserLoginInfo(provider, verifiedAccessToken.user_id));
然后如何创建不记名令牌完全取决于您,如果您按照下面列出的教程进行操作,您可以获得:
var tokenExpiration = TimeSpan.FromMinutes(30);
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim("role", "user"));
var props = new AuthenticationProperties()
{
IssuedUtc = DateTime.UtcNow,
ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
};
var ticket = new AuthenticationTicket(identity, props);
var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
来源,包含完整教程here
我还通过 SDK 收到了电子邮件,并将其与 POST 请求一起发送,因为我同时管理了 API 和消费者。不过警告:Facebook 用户可能不想给您电子邮件地址。
在 Android and
上登录 facebook 后获取电子邮件
我不明白为什么他们没有明确的教程或指南,所以我希望我的问题能在这里得到解答。
因此,尝试通过网络从 facebook 或 google 注册用户 Api。
问题是,在 RegisterExternal
方法中,这一行:
var info = await Authentication.GetExternalLoginInfoAsync();
它returns为null,因此返回一个BadRequest()
到目前为止我得到了什么:
在 Startup.Auth.cs
中,我已经知道了 ID 和秘密,请注意,我也尝试过使用 Microsoft.Owin.Security.Facebook
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions
{
AppId = "103596246642104",
AppSecret = "1c9c8f696e47bbc661702821c5a8ae75",
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook"));
return Task.FromResult(0);
}
},
};
facebookOptions.Scope.Add("email");
app.UseFacebookAuthentication(facebookOptions);
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "328779658984-t9d67rh2nr681bahfusan0m5vuqeck13.apps.googleusercontent.com",
ClientSecret = "ZYcNHxBqH56Y0J2-tYowp9q0",
CallbackPath = new PathString("/api/Account/ManageInfo")
});
facebookOptions 来源:this post
那个额外的 facebookOptions 没有解决问题。
我能够从 Google 和 Facebook 检索到 access_token。我还可以使用 access_token 到 api/Account/UserInfo
GET http://localhost:4856/api/Account/UserInfo
in the header:
Authorization: Bearer R9BTVhI0...
其中returns:
{"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}
我注意到他们的一个问题是 returns 我的名字作为电子邮件,而不是实际的电子邮件地址。
现在我想为我的数据库注册一个新用户的外部登录,我这样调用 POST:
POST http://localhost:4856/api/Account/RegisterExternal
[header]
authorization: bearer 6xcJoutY...
Content-Type: application/json
[body]
{"Email":"...@hotmail.com"}
来源:this post
现在这个 returns 这个代码片段上的 BadRequest,在 RegisterExternal():
public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//AuthenticationManger?
var info = await Authentication.GetExternalLoginInfoAsync();
if (info == null)
{
return InternalServerError();
}
在调试中,ExternalLoginConfirmationViewModel
确实包含我的电子邮件地址。
我做错了什么?我是否必须向 Startup.cs
添加一些内容?在 Startup.Auth.cs
中我还需要做些什么吗?我是否错误地调用了 RegisterExternal
?在 MVC 中如此顺利,为什么在 Web 中不行 API?
阿苏看了this answer from this question,但是没看懂怎么实现。
这种方法不太实用,因为你正在开发一个 API,很可能会用于应用程序,你最好的方法是处理 API 消费者使用 facebook 的登录,然后让他们向您发送一个 Facebook 身份验证令牌。
基本上我正在尝试这样做:
- 为 facebook 创建外部登录 link。
- 将用户发送到那个 link 将把他们带到 facebook 登录页面。
- 登录后 facebook 将重定向到 api。
- 用户将被注册,但是正在使用 API 的 app/website 是如何知道的?
你要做的是:
- API 消费者创建自己的 facebook 登录方法(对于通过 SDK 的应用程序)
- API 消费者将向 API 发送一个 facebook 令牌到 register/login。
- API 将使用 facebook 图表端点检查令牌。
- 成功后,API 将 return 一个不记名令牌,供 API 进行进一步的身份验证请求。
因此,作为 API 开发人员,您将像这样验证令牌:
var verifyTokenEndPoint = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", accessToken, appToken);
然后获取userId
var client = new HttpClient();
var uri = new Uri(verifyTokenEndPoint);
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
dynamic jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(content);
string user_id = jObj["data"]["user_id"];
string app_id = jObj["data"]["app_id"];
}
最终您会像这样创建或找到一个用户:
IdentityUser user = await _userManager.FindAsync(new UserLoginInfo(provider, verifiedAccessToken.user_id));
然后如何创建不记名令牌完全取决于您,如果您按照下面列出的教程进行操作,您可以获得:
var tokenExpiration = TimeSpan.FromMinutes(30);
ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
identity.AddClaim(new Claim("role", "user"));
var props = new AuthenticationProperties()
{
IssuedUtc = DateTime.UtcNow,
ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration),
};
var ticket = new AuthenticationTicket(identity, props);
var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
来源,包含完整教程here
我还通过 SDK 收到了电子邮件,并将其与 POST 请求一起发送,因为我同时管理了 API 和消费者。不过警告:Facebook 用户可能不想给您电子邮件地址。
在 Android and