ASP.NET CoreでOAuthを試す(2)
前回はGoogleAPI側の設定を行いました.
今回はアプリケーション側でGoogleのOAuthを利用する手順を説明します.
ExternalLoginCallback action in asp net core - YouTube
EFCoreでDBへ接続(作成)
プロジェクトもDBも新規に作成する場合は以下の記事を参考にして,Identityを導入してDBを作成するところまで行う. Update-Database
までできればOk.
Microsoft.AspNetCore.Authentication.Googleをインストール
Nugetでインストールします.
ConfigureServicesへの登録
ここでは前回取得したクライアントIDとシークレットが必要になるので,Google API Consoleのページを開いて「認証情報」タブで確認しておきます.
Startup.csのConfigureServicesメソッド内に以下を追加します.
services.AddAuthentication() .AddGoogle(options => { options.ClientId = "あなたのクライアントID"; options.ClientSecret = "あなたのクライアントシークレット"; });
機密情報をソースコードに入れたくない場合は,UserSecretを使うと安全に機密情報を扱うことができるのでおすすめです. その場合は以下の記事を参考にしてください.
同じくStartup.csのConfigureメソッドには以下の内容を追加します.
app.UseAuthentication();
簡単なログインページを作る
Viewsフォルダの下にAccountフォルダを作って,そこにLogin.cshtmlという名前のRazor Viewを作成します.
中身はこんな感じにしておきます
@model LoginViewModel @{ ViewBag.Title = "User Login"; } <h1>User Login</h1> <div class="row"> <div class="col-md-6"> <h1>External Login</h1> <hr/> @{ <form method="post" asp-action="ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl"> <div> @foreach(var provider in Model.ExternalLogins) { <button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Login using your @provider.DisplayName account."> @provider.DisplayName </button> } </div> </form> } </div> </div>
まだ,ViewModelやControllerを作っていないので動きませんが,こんな感じのページが表示される予定です.
Controllerを作る
Controllersフォルダの下にAccountController.csを作成します.
1つ目のアクションメソッドであるLoginメソッドは以下のとおりです.
これはページを表示させることが主な役割です.
[HttpGet] [AllowAnonymous] [Route("[action]")] public async Task<IActionResult> Login() { LoginViewModel model = new LoginViewModel { ReturnUrl = "", ExternalLogins = (await signInManager.GetExternalAuthenticationSchemesAsync()).ToList() }; return View(model); }
この一文ExternalLogins = (await signInManager.GetExternalAuthenticationSchemesAsync()).ToList()
でsignInManagerに登録した外部ログインプロバイダを取得します.Startup.csで登録したサービスの分だけここで取得されます.
もう一つアクションメソッドを追加します.こちらはGoogleログインボタンが押されたときのアクションです.
[AllowAnonymous] [HttpPost] [Route("[action]")] public IActionResult ExternalLogin(string provider, string returnUrl) { //Google側の認証が終わったらどのURLに遷移させるかを指定している var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }); var properties = signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); return new ChallengeResult(provider, properties);//Googleの認証ページが開く
"ExternalLoginCallback"って文字列はなんだよ,というところですが,これは後で説明するとして今はここまで.
あと、このAccountControllerでは以下のようにSignInManagerを受け取るようにしておきます。
private readonly SignInManager<IdentityUser> _signInManager; public AccountController(SignInManager<IdentityUser> signInManager) { _signInManager = signInManager; }
ViewModelを作る
ViewModelsフォルダの中にLoginViewModelを作成します.
public class LoginViewModel { /// <summary> /// ユーザーがログイン前にアクセスしたURLを入れる /// ログイン完了後にリダイレクトするURL /// </summary> public string ReturnUrl { get; set; } public IList<AuthenticationScheme> ExternalLogins { get; set; } }
このpublic IList<AuthenticationScheme> ExternalLogins
に外部ログインプロバイダが入ります.
さて,これでViewとControllerとViewModelが揃ったので動くようになったはずです.
デバッグしてみましょう.以下のようなGoogleのログインページが表示されると思います.
試しにログインを続行してみると,以下のページが表示され,
さらに「許可」ボタンを押すと,こうなります.
これは,
- Googleアカウントの認証は通った
- 通ったあと,通ったという結果を自分のサイトでどのように使うかは自分で作る.
- 通常は,通ったという結果をアプリケーションで受け取ったら,自分のサイトのIdentityの仕組みで新規ユーザーを作成してログイン状態にする
ということで,この外部サービスの認証に通った(または通らなかった)という結果を使って自分のサイトのログイン処理をしなければならないのに,それを行うコールバックが見つからないのでエラーになっている,ということです.
外部サービス認証成功後にコールバックを指定しているのは以下の部分で,ExternalLoginCallbac
というメソッドを指定しています.
var redirectUrl = Url.Action("ExternalLoginCallbac", "Account", new { ReturnUrl = returnUrl });
でもまだ作ってないので上記のエラーというわけです.
今回はここまでで,次回は外部サービスの認証結果を受け取って自分のサイトのログイン処理を行うコールバックの部分について書きます.