Web アプリにサインインする際、Microsoft Authenticator や Google Authenticator を使用して 6 桁の数字を入力する事が多くなったと感じます。そこで自分が作った Web アプリに TOTP (Time-based One-Time Password) 実装するにはどうしたら良いか、.NET 8 の Web アプリで試してみました。
Web アプリを作成
$ dotnet --version
8.0.100
$ dotnet new webapp --auth Individual -o WebApp1
$ cd WebApp1
$ dotnet run
QR コード追加前の画面

Web アプリに QR コードを追加
$ wget -O wwwroot/lib/qrcode.min.js https://raw.githubusercontent.com/davidshimjs/qrcodejs/master/qrcode.min.js
$ dotnet tool install -g dotnet-aspnet-codegenerator
$ dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
$ dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Manage.EnableAuthenticator"
$ code Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml
$ code wwwroot/js/qr.js
EnableAuthenticator.cshtml
<script type="text/javascript" src="~/lib/qrcode.min.js"></script>
<script type="text/javascript" src="~/js/qr.js"></script>
を追加。
@page
@model EnableAuthenticatorModel
@{
ViewData["Title"] = "Configure authenticator app";
ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
}
<partial name="_StatusMessage" for="StatusMessage" />
<h3>@ViewData["Title"]</h3>
<div>
<p>To use an authenticator app go through the following steps:</p>
<ol class="list">
<li>
<p>
Download a two-factor authenticator app like Microsoft Authenticator for
<a href="https://go.microsoft.com/fwlink/?Linkid=825072">Android</a> and
<a href="https://go.microsoft.com/fwlink/?Linkid=825073">iOS</a> or
Google Authenticator for
<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en">Android</a> and
<a href="https://itunes.apple.com/us/app/google-authenticator/id388497605?mt=8">iOS</a>.
</p>
</li>
<li>
<p>Scan the QR Code or enter this key <kbd>@Model.SharedKey</kbd> into your two factor authenticator app. Spaces and casing do not matter.</p>
<div class="alert alert-info">Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable QR code generation</a>.</div>
<div id="qrCode"></div>
<div id="qrCodeData" data-url="@Model.AuthenticatorUri"></div>
</li>
<li>
<p>
Once you have scanned the QR code or input the key above, your two factor authentication app will provide you
with a unique code. Enter the code in the confirmation box below.
</p>
<div class="row">
<div class="col-md-6">
<form id="send-code" method="post">
<div class="form-floating mb-3">
<input asp-for="Input.Code" class="form-control" autocomplete="off" placeholder="Please enter the code."/>
<label asp-for="Input.Code" class="control-label form-label">Verification Code</label>
<span asp-validation-for="Input.Code" class="text-danger"></span>
</div>
<button type="submit" class="w-100 btn btn-lg btn-primary">Verify</button>
<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>
</form>
</div>
</div>
</li>
</ol>
</div>
@section Scripts {
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript" src="~/lib/qrcode.min.js"></script>
<script type="text/javascript" src="~/js/qr.js"></script>
}
qr.js
下記のコードを新規作成。
window.addEventListener("load", () => {
const uri = document.getElementById("qrCodeData").getAttribute('data-url');
new QRCode(document.getElementById("qrCode"),
{
text: uri,
width: 150,
height: 150
});
});
QR コードが表示されるか動作確認
