web-dev-qa-db-ja.com

外部ログインWebAPIを登録する

なぜ彼らがこれに関する明確なチュートリアルやガイドラインではないのか理解できないので、私の質問がここで答えられることを願っています。

したがって、WebApiを介してFacebookまたはGoogleからユーザーを登録しようとしています。

問題は、RegisterExternalメソッドの次の行にあります。

_var info = await Authentication.GetExternalLoginInfoAsync();
_

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ソース: この投稿

その余分なfacebookOptionsは問題を解決しませんでした。

GoogleとFacebookの両方からaccess_tokenを取得できます。このaccess_tokenで_api/Account/UserInfo_に認証することもできます

_GET http://localhost:4856/api/Account/UserInfo
in the header:
Authorization: Bearer R9BTVhI0...
_

返されるもの:_{"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}_

私が彼らに気付いた問題の1つは、実際の電子メールアドレスではなく、私の名前が電子メールとして返されることです。

次に、データベースの新しいユーザーに外部ログインを登録します。これをPOST呼び出します:

_POST http://localhost:4856/api/Account/RegisterExternal
[header]
authorization: bearer 6xcJoutY...
Content-Type: application/json
[body]
{"Email":"[email protected]"}
_

ソース: この投稿

これで、RegisterExternal()内のこのコードスニピットでBadRequestが返されます。

_    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では非常にスムーズに進みますが、WebAPIではどうでしょうか。

麻生は この答え から この質問 を見ましたが、これを実装する方法がわかりませんでした。

13
CularBytes

この方法は実際には実用的ではありません。アプリで使用される可能性が最も高いAPIを開発しているため、APIコンシューマーがFacebookでログインを処理し、Facebook認証トークンを送信できるようにするのが最善の方法です。

基本的に私はこれをやろうとしていました:

  1. Facebookの外部ログインリンクを作成します。
  2. Facebookのログインページに移動するリンクにユーザーを送信します。
  3. ログイン後、FacebookはAPIにリダイレクトされます。
  4. ユーザーは登録されますが、APIを使用しているアプリ/ウェブサイトはどのように知っていますか?

あなたがしたいことはこれです:

  1. APIコンシューマーは、Facebookでログインするための独自のメソッドを作成します(SDKを介したアプリの場合)
  2. APIコンシューマーは、登録/ログインするためにFacebookトークンをAPIに送信します。
  3. APIはFacebookグラフエンドポイントでトークンをチェックします。
  4. 成功すると、APIは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);

ソース、完全なチュートリアル付き ここ

また、SDK経由でメールを受け取り、それをPOSTリクエストと一緒に送信します。これは、APIとコンシューマーの両方を管理したためです。ただし、警告:Facebookユーザーはあなたに提供したくない場合があります。電子メールアドレス。

Android および [〜#〜] ios [〜#〜] でFacebookにログインした後にメールを受け取る

5
CularBytes