kitak blog

Kみたいなエンジニアになりたいブログ

ASP.NET Core のアプリで Firebase 認証

.NET Core の gRPC とか C# の Firestore クライアントを触る - kitak blog で書いたアプリに Firebase の認証を組み込む。具体的にはクライアントの Firebase SDK で生成した ID トークンの検証をおこない、ユーザーの id を取得する。.NET Core のバージョンは 3.1.0

ASP.NET Core には認証や認可の機能が含まれているので、Startup.cs でそれぞれのサービスとミドルウェアを登録してあげればよい。事前に利用する認証スキームのパッケージをインストールしておく。Firebase Authentication の場合は Microsoft.AspNetCore.Authentication.JwtBearer

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

サービスの登録

[Project ID] は Firebase のプロジェクトIDで置き換える。

public void ConfigureServices(IServiceCollection services)
{

    // ...

    services.AddAuthorization(options =>
    {
        options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
        {
            policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
            policy.RequireClaim(ClaimTypes.Name);
        });
    });
    services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.Authority = "https://securetoken.google.com/[Project ID]";
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = "https://securetoken.google.com/[Project ID]",
                ValidateAudience = true,
                ValidAudience = "[Project ID]",
                ValidateLifetime = true
            };
        });

   // ...
}

ミドルウェアの登録

呼び出す順番が重要なので注意

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...

    app.UseAuthentication();
    app.UseAuthorization();

    // ...
}

アクセスの制御

実際にアクセスを制御するには、制御したい gRPC のサービスのクラスかメソッドに Authorize 属性を指定する。ユーザーの情報は ServerCallContext から取得できる。

[Authorize]
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
    var user = context.GetHttpContext().User;
    var uid = user.Claims.Where(claim => claim.Type == "user_id").FirstOrDefault().Value;
    
    // ...
}

.NET Core アプリを Cloud Run にデプロイする

.NET Core の gRPC とか C# の Firestore クライアントを触る - kitak blog で書いたアプリを Cloud Run にデプロイしてみた。

Docker を使用してアプリをコンテナー化するチュートリアル - .NET Core | Microsoft Docshttps://cloud.google.com/run/docs/quickstarts/build-and-deploy?hl=ja を参考に進めた。

Dockerfile は、こんなかんじ。

# Use Microsoft's official lightweight build .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-sdk/
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app

# Install production dependencies.
# Copy csproj and restore as distinct layers.
COPY *.csproj ./
RUN dotnet restore

# Copy local code to the container image.
COPY . ./
WORKDIR /app

# Build a release artifact.
RUN dotnet publish -c Release -o out

# Use Microsoft's official runtime .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS runtime
WORKDIR /app
COPY --from=build /app/out ./
ENV ASPNETCORE_ENVIRONMENT Production
ENV PORT 8080

# Run the web service on container startup.
ENTRYPOINT ["dotnet", "GrpcGreeter.dll"]

Cloud Run にデプロイするにあたって、Program.csCreateWebHostBuilder の定義を以下のように書き換える。ポートを環境変数で指定できるようにするのと、IPアドレス0.0.0.0 にする。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                string port = Environment.GetEnvironmentVariable("PORT") ?? "8080";
                webBuilder.ConfigureKestrel(options =>
                {
                    // Setup a HTTP/2 endpoint without TLS.
                    options.Listen(IPAddress.Any, int.Parse(port), o => o.Protocols = 
                            HttpProtocols.Http2);
                });
                webBuilder.UseStartup<Startup>();
            });
    }

イメージのビルド&デプロイはドキュメントの通りで、

gcloud builds submit --tag gcr.io/[PROJECT-ID]/greeter

gcloud beta run deploy --image gcr.io/[PROJECT-ID]/greeter

で、とっても簡単。

ちょっと前まで Windows だけでしか動かなかったサービスが Googleクラウドで動くのだから、すごい時代(コンテナ・ Docker が普及したのが大きそう)。

デプロイしたサービスのシャットダウンは GCP のコンソールから行う。

足の治療院に行ってきた 2020年1月

毎月行っている足の治療院へ。

ちょうど数日前にビルドアップ走をしてから、足首やら足の付根が痛くなっていたので、相談に乗ってもらった。日に日に痛みはなくなってきているので、普通に負荷がかかりすぎたんでしょう、とのこと。

心肺機能を向上させるために、週に1,2回、ゼーハーゼーハー言いながら走っているのだけど、そこまで追い込むと足にけっこうなダメージが与えているという課題が浮き彫りになった。筋肉が硬くて動きが悪いのを無理に動かそうとして、足がダメージを受けているので、ストレッチで筋肉を柔らかくして身体を動かしやすくしましょう、という話になった。
具体的には走り終わった後とかお風呂に入った後に、ふくらはぎ、腿前、腿裏、お尻の静的ストレッチを5分以上やる。アプリとか Pixela で記録をつけるといいかも。

.NET Core の gRPC とか C# の Firestore クライアントを触る

仕事で扱っていないフレームワーク・言語になにか触れてみようと思い、.NET Core (C#) を触ってみた。

C# は学生時代に Windows 向けのアプリケーションを授業で作ったとき以来に書く。当時はまさか、.NET のクロスプラットフォームオープンソースな実装が使える時代が来るとは全く思っていなかった。

とりあえず gRPC のサーバーを作ってみようと思い、以下のチュートリアルをやってみる。

docs.microsoft.com

gRPC が .NET Core にシームレスに統合されていて感動。Visual Studio Code .NET Core SDK (dotnet コマンド) の組み合わせでやったけれど、サーバーの起動まわり以外はハマることなく、さくさく進めることができた。チュートリアル中でもちゃんとケアしてくれているけれど、Mac OS では HTTP/2 over TLS でサーバーを起動できないので注意( .NET Core での gRPC のトラブルシューティング | Microsoft Docs を参照)、TLS を外したら次はクライアントで .NET Core での gRPC のトラブルシューティング | Microsoft Docs でハマるので注意。

DI コンテナも標準で ASP.NET Core に入っていてうれしい ( ASP.NET Core での依存関係の挿入 | Microsoft Docs )

gRPC のチュートリアルを一通りこなして、次は Firestore のクライアントを触ってみることにした ( Cloud Firestore を使ってみる  |  Firebase )。 ドキュメントを試しに書き込んでみたのだけど await で実行がフリーズしてしまった。調べたら、Firestore のクライアントが依存している gRPC のバージョンと、.NET Core が依存している gRPC のバージョンで互換性がないのが原因らしい。

github.com

次のメジャーバージョンでアップデートするそうなので( Major Version Plan | Google Cloud APIs )、一回休み。対応されるまでは、Entity Framework と MySQL の組み合わせを試してみる。

ランニング・マラソンを意識した食事

ここ数ヶ月、ランニング・マラソンで重要な栄養を意識して摂るように意識していたので、忘れないようにまとめておく。

栄養

ビタミンB1

疲労回復。豚肉の赤身、きのこ、大豆を意識して食べていた。ビタミンB1は以下に書くクエン酸と一緒に摂るのが効果的。

クエン酸

疲労回復。酢の物、柑橘類(オレンジ・グレープフルーツ)、梅干しを意識して食べていた。

走っていると毛細血管が壊れたり、赤血球が傷ついて鉄が不足する。鉄を多く含むのは、ひじき、あさり、卵など。

たんぱく質

筋肉を作る。豚肉の赤身、大豆、卵、魚の切り身を意識して食べていた。

カリウム

ミネラル。汗と一緒に排出されるので、その結果、体内のミネラルバランスが崩れると足が痙攣するので、日頃から意識的に摂る必要がある。カリウムを多く含むのはバナナ。

これらをバランス良く摂ろうとすると、自然と栄養バランスのよい献立になるのでおすすめです。例えばこんなかんじ。

献立案1

  • 梅干し入りのおにぎり
  • あさりの味噌汁
  • 豚肉の生姜焼き
  • キャベツ、きのこの炒めもの(付け合せ)
  • もずく酢
  • バナナ

献立案2

  • ご飯
  • 中華風卵スープ
  • 豆とひじきの煮物
  • 銀鮭の焼いたやつ
  • グレープフルーツ

福岡マラソン2019 ふりかえり

11/10(日)に福岡マラソンに参加した。前回が3月の鹿児島マラソンだったので、9ヶ月ぶり二度目の挑戦。

なんとかサブ4(4時間切り)を達成できた。もう半月以上、経ってしまっているけれど、次回のためにここに振り返りを書いておく。

練習

フルマラソンに向けて練習量を増やしたのは9月から。それまで週1回おこなっていたポイント練習を週2回に増やした。ポイント練習の内容は、インターバル走、ビルドアップ走。それ以外は疲労を抜くための軽めのジョグだった。練習メニューは小出監督の本を参考に組んだ。

ポイント練習を増やした結果、月間走行距離が120~140kmから180~200kmになった。これは、若干たるんでいる自分の身体からすると故障を起こすか起こさないかギリギリの練習量だった。強い痛みが出ることはなかったけれども、脛や足の付根に違和感が出ることがしばしばあった。
月に一度、足のメンテナンスのために通っている治療院の施術師にも、今の身体だとこれ以上はやめておいたほうがいいと警告された。

フルマラソンの練習のために1ヶ月~3週間前に30km走をやる人が多い。これは足の持久力をつける狙いがあるのと、単純に30km走りきったことが自信になって本番にリラックスして臨むことができる精神的な狙いがある。自分もやっておこうと思い、東京30k秋大会という荒川河川敷を走るマラソンの練習を兼ねた大会に参加したのだが、大会当日が最高気温30℃という10月ではありえない気温だった。

20kmくらいで身体がおかしくなってきたのでリタイアした。

この翌週は台風が関東を直撃して、断念。それ以降は大会まで3週間を切っているので、疲れを残さないために無理な練習はできない。結局、30km走は一度もできなかった。疲れをためない、故障を起こさないギリギリのところで、週に1度、皇居のまわりをぐるぐる20kmぐらい走っていた。ただ、足の脛の違和感が日に日に大きくなっていくのと、20kmでもけっこうバテバテで正直サブ4が達成できる気はしていなかった。

直前

1週間前に前述の足の治療院にいったときに「kitaさん、お尻の筋肉が全然使えてませんねぇ。お尻の筋肉を鍛えたほうがいいですよ」と言われて、今更言うんかい!という気持ちだったのだけど、走る前にお尻の筋肉を鍛える筋トレを始めた。たまたま先日、同じ筋トレを紹介するツイートを見かけたので貼っておく。

走るときもお尻の筋肉を意識するようにした。その結果、本番3日前に急に走り方に目覚めて、楽にそこそこ速いペースで走れるようになった。大会直前に必殺技をマスターする少年漫画のキャラみたいな気持ちだった。

思えば、鹿児島マラソンが終わった後はハーフマラソンに向けた練習をしていたので、足をとにかく動かしてスピードを出そうとする癖のようなものがついてしまって、お尻の筋肉はほとんど使っていなかったのかもしれない。

当日

ぐっすり眠れた。朝起きて、前日に買っておいたカステラ、バナナ、豆大福、炭酸抜きコーラを食べた。

天神の近くのホテルに滞在していたので、着替えてスタート地点に向かう。朝はちょっと肌寒かった気がする。
スタートまで時間があったので、トイレに並んだり、ストレッチをしていた。

集合場所のブロックに着いてから、スタートまで40分くらいあって、かなり退屈だった。またトイレに行きたくなって、スタート直前はけっこう限界だった。結局スタートして1kmぐらい走った後にトイレに行った。最初から思わぬ、時間ロスをくった。

その後は、キロ5:20~5:30のペースで走っていた。 スロースタートでいって、30kmからペースを上げる計画だったので、本当は5:40~5:50のペースで走るはずなのだけど(スタートからゴールまでキロ5:40のぺースで走り続ければサブ4達成)、ペースを落とそうと思ってもなかなか落ちないので、「まぁ、このペースで気持ちよく走れているのなら、それでいいか」ということにして、そのままのペースを維持した。
このペースで走り続けた結果、最初のトイレの時間ロスの借金を返して、その後は1キロにつき10~20秒の貯金を貯め始めた。コースが大体フラットで走りやすかった。

給水はすべて飲むとお腹にたまるので、2口だけ飲んだ。スポドリではない普通の水も定期的に取って、口に少し含んで、残りは足の腿、腕、首にかけて、身体を冷やしていた。一度ミスって、靴に思いきりかけてしまって、その後しばらく足が重くなってしまった。
栄養補給は前日に買ったエネルギー補充のゼリーを45分おきにとった。これが大正解で、決して美味しくはないんだけど独特の甘苦い味が口に広がるだけで、身体が楽になった気がした。

26kmぐらいまでキロ5:20~5:30のペースが続いて、そこからキロ5:40にペースが落ちた。といっても、このペースのままでもサブ4は達成できるし、なんだったらそれまでの貯金がかなり貯まっている、と油断したのもつかの間、31km地点の高低差25mの難所「のらん坂」でペースがガクっとキロ6:00まで落ちた。ここで、足の疲労も出てきて、しばらくキロ5:50~6:00で走っていた。
気温も20℃まで上昇してそこそこ暑い。貯めた貯金は確実に減ってきて、サブ4達成が怪しくなってきた。少しでもエネルギー消費を減らすために目を細めて視覚から入る情報をカットして脳が使うエネルギーを減らした(バカっぽいけど、意外と同じことをする人はいるらしい)。「あぁ、もうダメかな。人生最後のフルマラソンというわけではないし、サブ4達成は次回の楽しみにしようかな」という気持ちになっていた。

38km地点で応援の人が一斉に「来た来た!」とか言っていて、一体なにが来たのかと思ったら、頭に目印の風船をつけたサブ4のペースランナーだった。追い抜かれて気がめげそうになったけど、「ここで食らいつけばサブ4が達成できる、やれるところまでやってみよう」と気持ちを切り替えたら、身体が軽くなった。その後は「あと1キロだけがんばってみよう」と言い聞かせながら、キロ5:20から5:30のペースでゴールまで走り切ることができた。

勝因は直前に走り方のコツを掴んだこと、栄養補給、38km地点で気持ちを切り替えてラストスパートできたことだった。どれかが欠けていたら、多分、サブ4は達成できなかったと思う。 走り終わった後は足よりもお尻が痛かった。これは走り方が変わって、お尻の筋肉が使えた良い傾向だと思う。

今後

どこかのタイミングで限界がきて、記録にはこだわらずにただ楽しみながら走ろう、と思う日が来るかもしれないけれど、まだまだできる気がしている。 身体も改善の余地がある(いまだにお腹はたるんでいるし、体重はマラソンの適正BMIから+5kg)。負荷の高い練習に耐えられるように筋肉をつけつつ、体重を68kgぐらいまで落としたい。

サブ4を達成できたので、次はサブ3.75(3時間45分切り)を目指したい。そのために心肺能力とスピードの向上を図る必要があるので、次は春先の練馬のハーフマラソンに焦点を合わせてがんばる。

ランニング記録 9月4週目

9/23 ほぐしのジョグ

6:55/kmのペースで、6km。

9/24 ビルドアップ走

1時間ビルドアップ走。5:13/kmのペースで11.5km、前後に7:00/kmのペースで3.6km

9/25 疲労抜きジョグ

7:36/kmのペースで、4.1km

9/27 ジョグ

6:51/kmのペースで、6km

9/28 ジョグ

7:23/kmのペースで、5.8km

9/30 タイムトライアル

前後に軽めに3km、タイムトライアルは5:19/kmのペースで10km。

まとめ

9月の走行距離は202km。足の疲労がけっこう溜まったが、距離を積み重ねることができた。10月は疲労を抜きながら、本番に向けて調整していく。