タイトルのままです。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 です。


サンプル(再掲)