タイトルのままです。ASP.NET Core Razor Pages と Firebase Authentication を組み合わせた認証機能の作成方法を紹介します。
本稿の完成形サンプルはこちらです。
ASP.NET Core Razor Pages プロジェクト作成
プロジェクト名を付けます。

認証機能は無しで OK です。

ログインページの追加
Pages フォルダ配下に Login.cshtml を追加します。



また、ヘッダーに、Login.cshtml へのリンクを追加する。_Layout.cshtml を、次の様に編集する。
_Layout.cshtml
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>@ViewData["Title"] - ASPNETCore_Firebase_Auth_Google</title> <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" /> <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" /> <link rel="stylesheet" href="~/ASPNETCore_Firebase_Auth_Google.styles.css" asp-append-version="true" /> </head> <body> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container"> <a class="navbar-brand" asp-area="" asp-page="/Index">ASPNETCore_Firebase_Auth_Google</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between"> <ul class="navbar-nav flex-grow-1"> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a> </li> @*追加*@ <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-page="/Login">Login</a> </li> </ul> </div> </div> </nav> </header> <div class="container"> <main role="main" class="pb-3"> @RenderBody() </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2022 - ASPNETCore_Firebase_Auth_Google - <a asp-area="" asp-page="/Privacy">Privacy</a> </div> </footer> <script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/site.js" asp-append-version="true"></script> @await RenderSectionAsync("Scripts", required: false) </body> </html>
認証機能呼び出し UI の実装
Firebase SDK を利用して、ボタンクリックで Google での認証を呼び出す機能を実装します。実装は大きく分けて、次のことを行っています。
- Firebase SDK の読み込み
- Firebase アプリケーションの初期化
- Google の認証画面の呼び出し
なお、変数 firebaseConfig に含まれる情報は、Firebase の「プロジェクトの概要」>「アプリ(n個のアプリ)」>アプリケーションのギアアイコン > 「全般」>「マイアプリ」>「SDK の設定と構成」に記載のある設定情報を反映します。
Login.cshtml
@page @model ASPNETCore_Firebase_Auth_Google.Pages.LoginModel @{ } <input id="loginButton" type="button" onclick="login()" value="ログイン" /> @section Scripts { @*Firebase SDK の読み込み*@ <script src="https://www.gstatic.com/firebasejs/8.6.2/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-auth.js"></script> <script> //Firebase の設定情報 const firebaseConfig = { apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxxx", databaseURL: "https://xxxxxxxxxxxxxxxxxxxxxxxxx", projectId: "xxxxxxxxxx", storageBucket: "xxxxxxxxxxxxxxxxxxxxxx", messagingSenderId: "xxxxxxxxxxxx", appId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }; // Firebase アプリケーションの初期化 firebase.initializeApp(firebaseConfig); // 認証プロバイダとして、Google の認証機能を利用する var provider = new firebase.auth.GoogleAuthProvider(); // 認証機能の呼び出し firebase.auth().getRedirectResult() .then((result) => { // Google での認証後に呼び出される。result には認証情報が含まれる。 // ログインしたユーザー情報 var user = result.user; }).catch((error) => { // エラー処理 }); function login() { // Google の認証画面にリダイレクトする。 firebase.auth().signInWithRedirect(provider); } </script> }
=> ここまでで、Firebase Authentication を組み込むことができました。
Cookie を利用してサーバー側でログイン状態を維持する
Program.cs を次の様に編集し、Cookie を用いて認証状態を維持できるようにします。
Program.cs
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); //追加 builder.Services.AddAuthentication("MyCookieAuth").AddCookie("MyCookieAuth", options => { options.Cookie.Name = "MyCookieAuth"; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication();//追加 app.UseAuthorization(); app.MapRazorPages(); app.Run();
Login.cshtml を次の様に編集し、Firebase Authentication から返却される認証情報から、token と uid を Login.cshtml.cs に送信できるようにします。
Login.cshtml
@page @model ASPNETCore_Firebase_Auth_Google.Pages.LoginModel @{ } <form id="form1" method="post" hidden> <input id="token" asp-for="Credential.Token" /> <input id="uid" asp-for="Credential.Uid" /> </form> <input id="loginButton" type="button" onclick="login()" value="ログイン" /> @section Scripts { @*Firebase SDK の読み込み*@ <script src="https://www.gstatic.com/firebasejs/8.6.2/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/8.5.0/firebase-auth.js"></script> <script> //Firebase の設定情報 const firebaseConfig = { ... }; // Firebase アプリケーションの初期化 firebase.initializeApp(firebaseConfig); // 認証プロバイダとして、Google の認証機能を利用する var provider = new firebase.auth.GoogleAuthProvider(); // 認証機能の呼び出し firebase.auth().getRedirectResult() .then((result) => { // Google での認証後に呼び出される。result には認証情報が含まれる。 // ログインしたユーザー情報 //var user = result.user; document.getElementById("token").value = result.credential.idToken; document.getElementById("uid").value = result.user.uid; // サーバーに認証情報を送信 document.getElementById("form1").submit(); }).catch((error) => { // エラー処理 }); function login() { firebase.auth().signInWithRedirect(provider); // Google の認証画面にリダイレクトする。 } </script> }
続いて、Login.cshtml.cs を次の様に編集し、Login.cshtml から送られてくる token と uid を元に ClaimsPrincipal を作成し、HttpContext.SignInAsync メソッドを呼び出すことで、ASP.NET Core アプリケーション上でログインとします。
Login.cshtml.cs
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.Security.Claims; using Microsoft.AspNetCore.Authentication; namespace ASPNETCore_Firebase_Auth_Google.Pages { public class LoginModel : PageModel { [BindProperty] public Credential Credential { get; set; } public void OnGet() { } public async Task<IActionResult> OnPost() { if (!ModelState.IsValid) { return Page(); } if (Credential == null) { return Page(); } var claims = new List<Claim>() { new Claim(ClaimTypes.UserData, Credential.Token), new Claim(ClaimTypes.NameIdentifier, Credential.Uid) }; var identity = new ClaimsIdentity(claims, "MyCookieAuth"); ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(identity); await HttpContext.SignInAsync("MyCookieAuth", claimsPrincipal); return RedirectToPage("/Index"); } } public class Credential { public string Token { get; set; } public string Uid { get; set; } } }
=> Login.cshtml 上の「ログイン」ボタンをクリックすると、Login.cshtml.cs の OnPost メソッドが呼び出され、Index.cshtml にリダイレクトされます。リダイレクト後、Index.cshtml.cs にて、User.Identity.IsAuthenticated の値が true となっていること、MyAuthCookie が生成されていることが確認できます。UI 上にログインユーザー向けの機能を表示する場合、User.Identity.IsAuthenticated で判定すれば OK です。


サンプル(再掲)