ASP.NET Coreで認証付きシングルページアプリケーション環境(React)を作る
概要
ASP.NET Coreを使用し、認証付きのシングルページアプリケーション環境(React)を作成する。
SPAのテンプレートであっても、認証周りはRazorページで行なっているようです。
環境
- Ubuntu 20.04(WSL2でテスト)
- .NET 5
- SQLServer for Linux
前提ソフトウェアのインストール
- Node.js
- .NET Core
- EntityFrameworkCore
- SQLServer for Linux
Node.jsのインストール
sudo apt install nodejs
sudo apt install npm
nodejs -v
npm -v
.NET Coreのインストール
wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update; \
sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y dotnet-sdk-5.0
確認
dotnet --version
//5.0.402
EntityFrameworkCoreのインストール
dotnet tool install --global dotnet-ef
SQLServer for Linuxのインストール
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
sudo add-apt-repository "$(wget -qO- https://packages.microsoft.com/config/ubuntu/20.04/mssql-server-2019.list)"
sudo apt-get update
sudo apt-get install -y mssql-server
初期設定を行う(エディションの選択、ライセンスに同意、adminのパスワード設定)
sudo /opt/mssql/bin/mssql-conf setup
起動しておく
sudo systemctl start mssql-server
sudo systemctl enable mssql-server
補足(WSL2で動かしている場合のみ)
WSL2で動かしている場合はSystemdがPID=1ではないのでエラーが起きる
wsl2 genieで検索すれば対処法あり
ルートで実行
sudo -s
wget -O /etc/apt/trusted.gpg.d/wsl-transdebian.gpg https://arkane-systems.github.io/wsl-transdebian/apt/wsl-transdebian.gpg
chmod a+r /etc/apt/trusted.gpg.d/wsl-transdebian.gpg
cat << EOF > /etc/apt/sources.list.d/wsl-transdebian.list
deb https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
deb-src https://arkane-systems.github.io/wsl-transdebian/apt/ $(lsb_release -cs) main
EOF
apt update
apt install daemonize
apt install -y systemd-genie
実行
genie -s
起動時に実行する(引用:https://qiita.com/I_Tatsuya/items/9f85cdb9adc3adcf1abd)
.profileに追加
if [ "`ps -eo pid,cmd | grep systemd | grep -v grep | sort -n -k 1 | awk 'NR==1 { print $1 }'`" != "1" ]; then
genie -s
fi
source .profile
SQL Server コマンドライン ツールをインストールする
// curlのインストール
sudo apt-get update
sudo apt install curl
curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list | sudo tee /etc/apt/sources.list.d/msprod.list
ツールのインストール
sudo apt-get update
sudo apt-get install mssql-tools unixodbc-dev
/// ダイアログが2回出てくるのでyes
Pathを通す
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.profile
source ~/.profile
ローカル接続とデータベースの確認
sqlcmd -S localhost -U SA
//データベースの一覧
1> Select name from sys.databases;
2> go
//使用するデータベースを選択する
1> use <DatabaseName>
2> go
//テーブルの確認
1> Select name From sys.objects;
2> go
プロジェクトの作成
認証付きTemplateを使用してプロジェクトを作成する
//-au 使う認証の種類 -uld SQLite ではなく LocalDB を使用 -o 出力する場所
dotnet new react -au Individual -uld -o myapp
プロジェクトのトップで必要なパッケージを追加する
cd myapp
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design
SQLServerにアクセスするパスワードをUserSecretsで設定する
dotnet user-secrets init
dotnet user-secrets set DbPassword <your_password>
application.json 内の ConnectionStringsを変更
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=myapp;User Id=SA;"
}
Startup.csのデータベースアクセス文字列部分を変更
//using Microsoft.Data.SqlClient;
var builder = new SqlConnectionStringBuilder(
Configuration.GetConnectionString("DefaultConnection")
);
builder.Password= Configuration["DbPassword"];
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(builder.ConnectionString));
フロントエンド部分のパッケージをインストールする
cd ClientApp/
npm install
データベースの更新
ASP.NET Core Identityに必要なテーブルが作成される
実行してエラーが出ないことを確認しておく
dotnet run
dotnet ef database update
// 成功すると認証に必要なデータベースが作成される
(補足)vs code で SqlServer拡張を使用しデータベースの内容を確認する
vs code の拡張機能からSql Serverを検索、インストール
SQL Serverのタブが増えるので
CONNECTIONSの隣の+からconnection stringと名前を入力する
//Connection String
Server=localhost;Database=myapp;User Id=SA;Password=<your_password>
電子メール認証を有効にする
マイクロソフト公式ではSendGridがおすすめされていたのでSendGridを使用する
SendGridのアカウント登録等については説明しません
認証周りのコードをコードジェネレーターで作成し、修正する
初期設定ではユーザー登録時にメールを送信せず、メール認証できるリンクが表示される。
この設定を変えなければならないが、ログイン周りのファイルはRazor Pageに統合されていており、非表示でコードの編集もできない。
そのため編集が必要なファイルを生成する必要がある。
dotnet-aspnet-codegeneratorのインストール
dotnet tool install -g dotnet-aspnet-codegenerator
プロジェクトにpacakgeを追加する
packageのインストールはプロジェクトのルートフォルダで行う必要がある
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.AspNetCore.Identity.UI
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet restore
ファイルを生成する
必要なファイルのみ生成する
dotnet aspnet-codegenerator identity -dc myapp.Data.ApplicationDbContext --files "Account.RegisterConfirmation"
すべてのファイルを生成する
dotnet aspnet-codegenerator identity -dc myapp.Data.ApplicationDbContext
メール認証の設定を変更する
Area/Identity/Pages/Account/RegisterConfirmation.csが生成されるので
以下の用に修正する
DisplayConfirmAccountLink = false;
SendGridの設定
SendGridをプロジェクトに追加する
dotnet add package SendGrid
必要なクラスを作成する
電子メールキーのクラスを作る
namespace myapp.Services
{
public class AuthMessageSenderOptions
{
public string SendGridUser { get; set; }
public string SendGridKey { get; set; }
}
}
EmailSenderを実装する
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
using SendGrid;
using SendGrid.Helpers.Mail;
using System.Threading.Tasks;
namespace myapp.Services
{
public class EmailSender : IEmailSender
{
public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor)
{
Options = optionsAccessor.Value;
}
public AuthMessageSenderOptions Options { get; } //set only via Secret Manager
public Task SendEmailAsync(string email, string subject, string message)
{
return Execute(Options.SendGridKey, subject, message, email);
}
public Task Execute(string apiKey, string subject, string message, string email)
{
var client = new SendGridClient(apiKey);
var msg = new SendGridMessage()
{
From = new EmailAddress("your_mail_address", Options.SendGridUser),
Subject = subject,
PlainTextContent = message,
HtmlContent = message
};
msg.AddTo(new EmailAddress(email));
// Disable click tracking.
// See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
msg.SetClickTracking(false, false);
return client.SendEmailAsync(msg);
}
}
}
SendGridのユーザーとApiKeyを設定する
dotnet user-secrets set SendGridUser <userName>
dotnet user-secrets set SendGridKey <key>
SendGridの設定をスタートアップで行う
// requires
// using Microsoft.AspNetCore.Identity.UI.Services;
// using myapp.Services;
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
ユーザー登録してメールが送信されていれば完了です
おわりに
MVCやWebAPIであっても大まかな流れは同じだと思います
MySQL等でも接続文字列やEntityFrameworkをMySQL用にすればいけそうかも
Discussion