プリザンターに会計freee C# SDKを導入してみた

皆さんお待たせしました!

先日2019/10/16(水)に提供開始の「会計freee C# SDK」をプリザンターに導入してみました。

2019/11/06 17:00 記事訂正:記事公開時SDK のリリース日が2018年になっておりました。正しくは2019年となります。記事を訂正いたしました。

今回はIIS独自の技術検証の記事です。アドオンプロダクトの発表というわけではありません。またIIS独自の検証のためプリザンターのバージョンアップで動作しなくなる可能性があることをご理解ください。

なぜfreeeとプリザンターなのか

どちらも中小規模の組織に対して強みのあるプロダクトなのではないかと(筆者が)思っています。そのため連携できると嬉しい方が多いのではないかと(筆者が)思っています。

そして何より次の表を見てください。

freee C# SDK プリザンターLinux
動作環境 .NET Core 2.2 .NET Core 2.2
フレームワーク ASP.NET Core MVC ASP.NET Core MVC

完全に一致しています。そしてプリザンターはGitHubソースコードが公開されており、改変が可能です。

※ちなみにLinux版とは.NET Core版(.NET CoreはLinuxでも動作する)の事なので、Windowsでも試せます。

これは試すしかありませんよね?

注意点

  • 会計freee C# SDKは素晴らしいプロダクトです。今回出てくるSDKの案内通りでない点は、プリザンターという既存のプロダクトに導入するために必要だった変更点です。
  • SDKの案内は新規に作成したプロジェクトに導入するもので、既存のプロジェクトへ導入ではないので読み替えが必要なことは当然です。どちらかが何かが悪いということではありません。
  • プリザンターは4年前にGitHubに公開されたプロダクトです。年単位で継続しているプロダクトに負債がないわけがありません。
  • プリザンターLinux版は.NET Frameworkでも.NET Coreでもどちらでも使えるようにしているという珍しい形態になっています。通常の.NET Coreアプリとは違ったところが出てきます。

今回の記事はプリザンターというプロダクト固有の事情が多いですが、どんなプロダクトでも多かれ少なかれ事情も負債もあるはずです。そのような事情や負債を乗り越えた一例としてヒントとなれば幸いです。

概要

「会計freee C# SDK」のReadmeのSDKの導入方法をなぞって、プリザンターに導入してみました。
繰り返しになりますが、新規プロジェクトへの導入方法を既存プロジェクトに適用するので前提が違っている点をご承知ください。

できるようにしたこと

プリザンターで次の事ができるようにしました。

  • freeeのアカウントでログインできるようにした (既に独自のログイン機能を持っている上に)
  • freeeユーザー情報を表示するページの追加

SDK導入方法の内容そのままです。

~~~やってみよう!~~~

プリザンターのデバッグ実行

プリザンターはGitHubからソースコードをダウンロードしても実行するのが難しいのが特徴の一つです。次の記事を参考にまずデバッグ実行できるようにします。

また、導入方法はVisual Studio Codeを使用していますが、今回はVisual Studioを使ってみました(筆者がプリザンターをデバッグする際に普段からVisual Studioを使っているため)。
Visual Studioでそのままデバッグ実行するとIIS Express上で実行されてしまいます。別にそれでも何とかなるのですが、実行環境を導入方法と合わせるためにデバッグ時に次の図のようにしてアプリケーション名を選択します。
f:id:imageinformationsystem:20191105180733p:plain
(ここではSDKのサンプル、BasicWebAppを選択しています)

GUIDの生成

導入にGUIDを作成する手順があります。どのようにGUIDを作るかは自由ですが、Visual StudioにはGUID作成機能があるのでその機能で作りました。
f:id:imageinformationsystem:20191105180836p:plain

SDKの追加

折角Visual Studioを使っているのでGUIでNuGetパッケージをインストールしてみました。
検索すると、バージョン番号に-Previewとついていないバージョンが見つかったのでこれをインストールしました。

<ItemGroup>
  <!-- [2] ここから -->
  <PackageReference Include="Freee.Accounting.Sdk" Version="1.0.0" />
  <PackageReference Include="Freee.OAuth.AspNetCore" Version="1.0.0" />
  <!-- [2] ここまでを追加 -->

f:id:imageinformationsystem:20191105181137p:plain

認証処理の書き換え

プリザンター自身が認証機能を持つため既存の機能とSDKとが混ざったコードになります。フィールド Configuration の大文字小文字が違っているなど、間違いさがしレベルのアドリブが必要です。

※上:導入方法のコード 下:実際に書いたコード

Configurationとconfigurationの違い

options.ClientId = Configuration["Freee:ClientId"];
options.ClientSecret = Configuration["Freee:ClientSecret"];
options.SaveTokens = true;
options.ClientId = configuration["Freee:ClientId"];
options.ClientSecret = configuration["Freee:ClientSecret"];
options.SaveTokens = true;

その他微妙な違い

services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = FreeeAuthenticationDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddFreee(options =>
        {
            options.ClientId = Configuration["Freee:ClientId"];
            options.ClientSecret = Configuration["Freee:ClientSecret"];
            options.SaveTokens = true;
        });
services.AddAuthentication(
    options =>
    {
        options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = FreeeAuthenticationDefaults.AuthenticationScheme;
    }
    ).AddCookie(o => o.LoginPath = new PathString("/users/login"))
.AddFreee(options =>
        {
            options.ClientId = configuration["Freee:ClientId"];
            options.ClientSecret = configuration["Freee:ClientSecret"];
            options.SaveTokens = true;
        });

実行時のURL

ASP.NET Core MVCは何の設定もせずコマンドから実行すると https://localhost:5001 で実行されます。プリザンターのソースコードVisual Studioで実行すると、違うポートで実行されるので設定を書き換えます。

Implem.Pleasanter.NetCore/Properties/launchSettings.json の Implem.Pleasanter.NetCore の applicationUrl を https://localhost:5001;http://localhost:5000 に変更します。

{
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:65195/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Implem.Pleasanter.NetCore": {
      "commandName": "Project",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      },
      "applicationUrl": "https://localhost:5001;http://localhost:5000"
    }
  }
}

Views\Shared_LoginPartial.cshtmlを新規作成

.cshtml。ビュー(Razor)の作成です。プリザンターは前述の

という背景のため.NET Framework時代のRazorが使われています。文法が違っていますので、_LoginPartial.cshtmlは次のようになります。

<ul class="navbar-nav">
    @if (User.Identity.IsAuthenticated)
    {
        <li class="nav-item">
            <a class="nav-link text-dark" href="@Url.Content("~/Account/Me")">Hello @User.Identity.Name!</a>
        </li>
        <li class="nav-item">
            <a class="nav-link text-dark" href="@Url.Content("~/Users/Logout")">Logout</a>
        </li>
    }
    else
    {
        <li class="nav-item">
            <a class="nav-link text-dark" href="@Url.Content("~/Account/Login")">Login</a>
        </li>
    }
</ul>

Views\Shared_Layout.cshtmlに_LoginPartialパーシャルを追加

前項同様、構文が変わります。

<!DOCTYPE html>
<!-- [1] ここから -->
@Html.Partial("_LoginPartial")
<!-- [1] ここまで追加 -->
@RenderBody()

これで生まれるHTMLソースは、HTMLとして正しくないものになります。しかしプリザンターでは生まれるHTMLソースが非常に困難であることと、これでもブラウザが良い感じに解釈してくれるので今回はこれで実装しました。

freeeのアカウントで名前を設定しておく

プリザンターの都合で、SDKを導入して動かす前にアカウントの名前を設定しておく必要があります。名前が設定されているかはSDKのサンプルBasicWebAppでも確認できます。名前が設定されていれば、「Hello 名前!」と表示されますが、空白のままだと「Hello !」となっていると思います。

認証されると、freeeユーザーの名前が@User.Identity.Nameに設定されます。そしてこの@User.Identity.Nameがプリザンターの内部処理ではログインユーザーのIDとして扱われます。

つまり、@User.Identity.Nameが空白だとプリザンター上では未ログインとして扱われてしまいます。

名前でPleasanterのユーザーを作っておく

プリザンターでは@User.Identity.NameをログインユーザIDとして扱うことを前項で説明しました。実はさらにこのログインユーザーIDでプリザンターのユーザーデータを探して、そこから権限の情報を取得します。
この時に権限の情報を取得できなくても未ログイン扱いになります。

そこで、今回のように外部の認証を利用する際にも同じ名前のユーザーを事前にプリザンター上に作っておく必要があります。
※これは他のシステムで認証する場合でも基本的に同様です。

ログイン成功

ここまでの手順で、freeeのアカウントでプリザンターにログインできるようになりました!
f:id:imageinformationsystem:20191105182227p:plain
f:id:imageinformationsystem:20191105182240p:plain

簡単ですね。

アカウント情報を表示 AccountController、Views\Account\Me.cshtml を新規作成

導入方法から特別変える点はありません。Me.cshtml も変更しなくてOKです。
f:id:imageinformationsystem:20191105182347p:plain

簡単に組み込める

素晴らしい「会計freee C# SDK」によって、簡単に会計freeeとプリザンターが連携できました。会計freeeとプリザンター、組み合わせることで高いシナジーが得られると思います(個人の感想です)。

ぜひ検討してみてください。そして...

プリザンター導入に際してカスタマイズをご検討されている方は是非ご相談ください!

IISはプリザンターのカスタマイズの経験が豊富です。プリザンター導入に際してカスタマイズをご検討されている方は是非ご相談ください! またご不明点やご質問などございましたら弊社までお問い合わせください。