👋

Blazor WebAssemblyで新規の業務システムを開発している話

2022/12/21に公開

背景

bitflyerの12/22のアドベンドカレンダーは、「Blazor WebAssemblyを用いた新規の業務システムの開発(現在進行中)」の話をしたいと思います。Blazor WebAssemblyを検討している人や現在開発中の方の手助けになればと思います。

bitFlyerのバックエンドの言語は基本的にC#で、クラウドはAzureを使用しています。そのため、他のクラウドを使用している場合は、一部異なる可能性があります。

また、検討および開発を2022年4月下旬に開始したため、最新と多少異なる可能性があります。

bitFlyerでのバックエンドの開発環境は、

個人的にWeb Formsは開発がしづらいため触りたくない(自分だけではないはず!)。
また、技術的に古いため、セキュリティ的に移行すべきではないかと思いました。

そこで、新規の業務システムを提案しました。
その際に、

  • どのように開発環境などを選んだ
  • 開発中にぶつかった壁や問題など
    などを説明します。

開発環境の選定

既定の開発環境

この3つは、社内の方針から、既定となっていました。

新システムの方針

新規のシステムの開発・開発環境の選定にあたり、以下のことを重要視しました。

  • 開発や運用を可能な限り属人化しない
  • 学習コストが低い
  • 社内システムであるため、フロントエンドの開発もバックエンドエンジニアのみで行うことを可能にする

以上のことから、Webフレームワークとして、Blazorを選択しました。次のサーバーサイドやフロントエンドの選定の説明をします。

サーバーサイド関連

Webフレームワーク

C#のWebフレームワークの選択肢として、

  • .Net Framework 4.8
  • .Net Core 3.1(もうすぐサーポートが切れる)
  • .Net 6

が挙げられますが、最新のものとして.Net 6を選択しました。

フロントエンド関連

Blazor Server or Blazor WebAssembly

Blazorには、ServerとWebAssemblyの2つがあり、Blazor WebAssemblyを選択しました。
その理由としては、

UI Componentの選定

Blazor WebAssemblyのフロントエンドの開発を簡潔にするUI Componentの選定です。
(UI Componentの選定 Confluence参照)
BlazorのUI Componentとしては以下のようなものがあります。

  • MatBlazor
  • Ant Design Blazor
  • Radzen
  • Syncfusion
  • Skclusive.Material.Component
  • Blazorise
  • BlazorStrap
  • PanoramicData.Blazor
  • MudBlazor
  • Element Blazor
  • Blazored

参照
https://blazor-master.com/blazor-ui-framework/
https://medium.com/@alexandre.malavasi/top-10-nice-free-blazor-components-b42875e56b28

選定基準

  • リリース頻度
    • 最近更新が行われていないものは除外
    • 定期的にリリースされているもの
  • リリースバージョン
    • 1.0.0以上のもの
  • Githubのスター数
  • 学習・開発コスト,開発のしやすいさ
  • コンポーネント数・ドキュメントの内容
  • 費用面は要相談
リリース頻度 リリースバージョン Githubのスター数 学習・開発コスト 開発のしやすいさ コンポーネント数 ドキュメントの内容 費用
MatBlazor × 2019/9/10で止まっている 〇 1.7.2.3 ◎ 2.7k ??
Ant Design Blazor × v0.10.7 ◎ 4.2k
Radzen ◎ 3.18.11 1.7k 〇 条件あり
Syncfusion ?? ×
Skclusive.Material.Component × 2020/12/6 ◎ 5.2.0 × 375 ?? ??
Blazorise × 2020/4/18 × 0.9.0 ◎ ×2.3k ?? ??
BlazorStrap × ?? ??
PanoramicData.Blazor × × × - - -
MudBlazor ◎ 2022/5/4 ◎ 6.0.10 ◎ 3.2k ?? -
Element Blazor - - × - - -
Blazored - - × - - -

総合的にみると、以下の3つに絞りました。

  • Radzen
  • Syncfusion
  • MudBlazor

Syncfusionは費用面($2,495/1Develper/1year)に問題があり、MudBlazorはドキュメントが不十分である(2022/04時点)ため、Radzenを選びました。

インフラ

Blazor WebAssemblyを乗せるリソースですが、

  • 社内システム
  • 利用者数の増減はそれほど大きくない
  • SREの知見が多い
    ということで、App Service(Windows)を選択しました。

認証

Blazor WebAssembly AAD認証

Blazor WebAssemblyの新規プロジェクト作成時に、認証を選ぶことができます。その際に、AADを選択するか、AADの登録を行った後、コマンドを使うことで簡単に新規プロジェクトを作成することができます。

注意点としては、AADのページの”アプリの登録”からクライアントサイド用とサーバーサイド用の2つを新規登録する必要があります。

詳細な手順は以下のページを参照してください。
https://learn.microsoft.com/ja-jp/aspnet/core/blazor/security/webassembly/hosted-with-azure-active-directory?view=aspnetcore-7.0

AADにおける権限設定

AADでは、これら3つを組み合わせて権限を設定します。

  • ロール
  • ユーザー
  • グループ
    簡単な図で表すと以下のようになります。

    1つのシステムに対し複数のグループを作成し、そこにユーザーとロールを割り振ります。

開発中にぶつかった壁や問題など

認証情報の保存先

Blazor Webassemblyの認証情報の保存先(デフォルト)はsession storageとなっています。また、クライアント側の設定でlocal storageに変更することができます。しかし、SessionStorageはXSSに弱いという問題点があります。
この点をMicrosoftに問い合わせたところ、Blazor Webassemblyのライブラリでは、認証情報をcookieに保存することができないという回答を得ました。

クエリの長さ制限

クライアントサイドからサーバーサイドのAPIを呼ぶ際に、デフォルトでクエリの最大長さが決まっています。それを超えるとエラーが出るため、クエリの最大長さを大きくする必要があります。App Service(Windows)を使用しているため、Web.configで更新することができ、以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <location path="." inheritInChildApplications="false">
        <system.webServer>
            <security>
                <requestFiltering>
                    <requestLimits maxQueryString="10000" />
                </requestFiltering>
            </security>
        </system.webServer>
    </location>
</configuration>

appsettings.XXXXX.json

サーバーサイドおよびクライアントサイド両方に、以下の4種類のappsettings.jsonがあります。

  • appsettings.json
  • appsettings.development.json
  • appsettings.stating.json
  • appsettings.production.json

どの環境なのかをわける指標がASPNETCORE_ENVIRONMENT であり、App Serviceに設定する必要があります。また、サーバーサイドおよびクライアントサイド共通で設定することが可能です。

https://learn.microsoft.com/ja-jp/aspnet/core/blazor/fundamentals/environments?view=aspnetcore-7.0

アクセストークン

サーバーサイドのAPIではアクセストークンによる認証で動作しています。アクセス トークンの既定の有効期間には、60 分から 90 分 (平均 75 分) の範囲のランダムな値が割り当てられます。
Blazor WebAssembly画面にあるログアウトボタンを押しても、アクセストークンは無効になりません。

https://learn.microsoft.com/ja-jp/azure/active-directory/develop/active-directory-configurable-token-lifetimes#access-tokens

採用

現在、bitFlyerではエンジニアを募集中です。皆さんの応募を待っています!

https://bitflyer.com/ja-jp/recruit#positions

また、個人的な話ですが、Wantedlyでインタビューを受けました。そちらの記事も読んでいただければ幸いです。

https://www.wantedly.com/companies/company_7215089/post_articles/439412

Discussion