OmniAICreator/Qiita-1.07M huggingface dataset:
「バックエンドエンジニアを目指す人のためのRust」を読み始めた人のメモ

Rust環境は導入済みなところからはじまります。

### Cargoのバージョン情報
```
cargo --version
```
```
cargo 1.79.0 (ffa9cf99a 2024-06-03)
```

### 新しいプロジェクト作成
```
cargo new hello_world
```
これで、デフォルトの入れ物ができあがりました。
```
hello_world/
├── Cargo.toml
└── src/
    └── main.rs
```

ディレクトリ構成図作成には[https://qiita.com/naoyuki2/items/940af4f9b0189b4f3259](https://qiita.com/naoyuki2/items/940af4f9b0189b4f3259)から教えていただいた[https://tree.nathanfriend.com/](https://tree.nathanfriend.com/)を使用しました。

### ビルドのみ

```
cargo build
```

### ビルドと実行

```
cargo run
```

### 静的解析
```
cargo clippy
cargo clippy --fix --allow-dirty
```
指摘出力と、自動修正のコマンド。

### フォーマット
```
cargo fmt
```
こっちは実行すれば自動修正される。

### VSCodeにrust-analyzer導入

導入済みでしたが、エラーが出ていたため、同じディレクトリにある古いパッケージを削除したり、rust-analyzerをアンインストール→再インストールしたりしました。

### clippyとfmtの自動実行

```json:.vscode/settings.json
{
    "[rust]": {
        "editor.defaultFormatter": "rust-lang.rust-analyzer",
        "editor.formatOnSave": true
    },
    "rust-analyzer.checkOnSave": true,
    "rust-analyzer.check.command": "clippy",
}
```

静的解析とフォーマットが、rsファイルの保存をトリガーとして実行されるようにします。
これによって、フォーマットが自動実行され（不要なダブル改行がシングルになる、など）、clippyによる注釈が波線でつくのを確認しました。

### コメント

```rust
fn main() {
    // お馴染みの、このタイプ
    println!("Hello World!"); // このタイプももちろんある
                              /*
                              複数行のコメントも
                              できますよ
                              しかもなんと、/* 入れ子 */ にもできるんだって
                              */
}
```

今後の開発が便利になりました。
詳細は書籍をご参照ください。

読み進めていくとわからないところだらけですが、実際の動きも見ながら勉強できて楽しいです。

ひとまず、一冊読み切ってやりきることを、来年第一期の目標としたいと思います。
iPhoneショートカット活用術：オートメーション編



iPhoneの「ショートカット」アプリには、特定の条件をトリガーにして自動的にいろいろなアクションを実行してくれる「オートメーション」機能があります。私はこの機能を使うことで、ちょっとした手間を減らしながら、毎日の生活をスムーズにしています。この記事では、実際に私がどんなオートメーションを設定しているか、その具体例を紹介します。

---

### 朝のルーチンを自動化
朝はいろいろと慌ただしく、やることも多いですよね。私は「目覚ましが止まったとき」をトリガーにして、いくつかのアクションをまとめて動かしています。

1. **天気予報を読み上げる**  
   まず「天気」アプリから情報を取得し、その日の天気と気温を読み上げるように設定しています。寝起きでまだぼんやりしていても、聞いているだけで外の様子がわかるので便利です。

2. **カレンダーの予定を表示**  
   同時に、その日入っている予定を一瞬で確認できるようにしています。カレンダーを開く作業を省けるので、「今日は何があったっけ？」と見落とすことも減りました。

---

### 自宅に着いたら自動で快適モードに
次におすすめしたいのが、「自宅に到着したとき」をトリガーにするオートメーションです。GPSを使った位置情報の仕組みで、家に入るタイミングを検出してもらいます。

- **Wi-Fiをオンにする**  
  外出時にモバイル通信をメインで使っていると、Wi-Fiをオフにしたまま忘れてしまいがち。そこで、家に着いたとき自動的にWi-Fiをオンにすることで、スムーズにネット回線を切り替えています。

- **音楽を再生してリラックス**  
  長時間移動して疲れたときは、リラックスできる音楽を聞きたいもの。帰宅と同時にプレイリストを再生するよう設定しておくと、一息つく時間も快適になります。

---

### 定型メールの送信を自動化
仕事やプライベートで、毎週・毎月決まったタイミングで送らないといけない連絡はありませんか？ 私は「曜日と時刻」をトリガーに設定して、定型メールを自動送信するようにしています。

- **報告メールやリマインドメール**  
  毎週月曜日の朝に上司へ週報メールを送る必要があるので、あらかじめ書いておいた文面を自動送信に設定。うっかり送り忘れるリスクが減りましたし、朝の貴重な時間を節約できます。

---

### まとめ＆ちょっとしたコツ
オートメーションを活用すると、いつも繰り返していた作業がラクになり、より重要なことに時間を使えるようになります。最初は「どんなタイミングで何を自動化しよう？」と戸惑うかもしれませんが、自分がよく行う作業や「これ、毎回やるの面倒だな」というところから始めてみるといいですよ。

- **オートメーションの通知を確認する**  
  iOSのバージョンによっては、オートメーションが実行される前に通知が表示されることがあります。通知が邪魔に感じる場合は、設定を見直してオン・オフを調整してみてください。

- **アプリの権限設定をチェック**  
  位置情報や通知など、アプリの権限がオフになっていると、うまく動かないことがあります。動作しない場合は、設定アプリを開いて権限を再確認してみてください。

このように、自分の生活スタイルに合ったオートメーションを組み合わせていくと、iPhoneが頼もしいパートナーになってくれます。ぜひ一度試してみて、あなただけの快適なルーチンを作り上げてみてください。
米田の補題 #22 自然変換

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# 自然変換
めちゃくちゃ理解しにくいです。
用語の意味が厳密になっている必要もありますが、入れ子構造なのが問題です。
（補足はあとで）
目的ない人にプログラミング言語をどうしても一つだけ勧めるなら

そもそもプログラミングするにあたって、何に苦労すると思いますか？
- ポインタやオブジェクト指向とかよくわかんない概念を学習するとき？
- 競プロとかでタイムアウトになって、アルゴリズムを学ばなければいけないこと？
- 数学を（ちょっと）使わなければいけないとき？
- すぐバグとか発生するとき？
しかもエラーが英語でこれを読まなければいけないとき？

...と色々あると思いますが、上の状況では一応スタート地点には立つことができていると思います。

# エピソード０のつまづき
ほんとの初めに苦労するのは、実は「環境構築」なのではないかなと思います。
いや、ググってインストールすればいいだけじゃん...といわれれば、まあそうなんですが、そうじゃないときがあったりもするのが、~~世の中~~です。

たとえば、検索して何らかのサイト参考にして、ダウンロードはできました、インストールはできました、と。でも、実行！...できない、みたいになるときもあります。例えばよくあるのが、パスを通さなければいけないとか。で、パスをなんとか通しました。でも、動かない。あ、再起動しなければいけないのね、で再起動するが動作しない。
...実はパスの打ち間違いだった、というような初歩の初歩でつまづくことがあります（昔の私の実体験）。
一つ一つは小さなエラーでも、そのエラー対処に数時間かけるってなるとそれだけでモチベーションは一気に下がります。もちろん、解決した後の達成感も格別ではあるのですが、簡単であることに越したことはありません。

# インストールしたくない！
そこで、インストールせずにプログラミングしたいと考えたときに、ぱっと出てくるのが、```Google Colaboratory```、つまり、**Python**です。
必要なものはGoogleアカウント。
エディターもいりません。ブラウザで書いて、ブラウザで実行できます。しかも、セル単位で実行できます。なので、たった一行を試したい...というときも、わざわざファイル作ってファイル名考えて、なんてしなくてよくなります。

もちろん、どの言語であろうとメジャーなものなら、ブラウザで実行できるサイトが多々あったりするのですが、意外とライブラリが対応してないとかオンライン保存とかの面で優れているのではないかと思ってます。
米田の補題 #21 関手の種類

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# 関手の種類
[wikipedia](https://ja.wikipedia.org/wiki/%E9%96%A2%E6%89%8B)を見ればわかるように、色んな種類があります。関手は、圏の圏の射であるとされますが、そもそも、実際によくあつかう圏はモノイドで図式的にいえば対象がひとつの簡単な事例です。関手も自己関手がありますが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/e326f252-924c-9b46-2a80-88d7c680466d.png)
醍醐味は対象が2つの場合でしょう。（図が下手ですみません）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48387/ade409f0-a3d0-5176-3ecf-8562cf6ab154.png)
対応は、射と異なり対象間はひとつです。企画進行への応用は、あまり単純すぎてこのままでは、使えない気がしますね。通常の会議での会話や、企画進行の実態は、遥かに複雑な気がします。マインドマップなどで項目数が多く複雑な図を書くのはよくあります。複雑な図はなにかに役立っているのでしょうか？　プロジェクトマネジメントを学ぶ人や資格を持っている人は、多いですが、炎上事件はえんえんと続き、炎上しないほうが不思議です。プロジェクトマネジメントや、企画進行は、非常に難しいものだというのが本質ではないでしょうか？

**米田の補題川柳　数学は企画と違い簡単だ**
色々考えた私の結論です。モノイドは、企画進行で使用する矢印とはかけはなれています。では、どうしたらいいかというと、カンバンと呼ばれるissue tracking system を効率よくつかうことに、応用すればいいかなというのが、現時点での私の結論です。
圏を想定する場合、対象は、４つまで、射については、複数ある前提ですが、とりあえず対象間はひとつとします。

**米田の補題川柳　関手補足**
企画だとまず圏からが手始めだ
サーバーサイドエンジニア向け2024年のセキュリティトレンド

![マインドマップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/9965a343-1c61-d117-1c02-195a05f2b964.png)


## 2024年のWebアプリケーションセキュリティとサーバーサイドの対策

Webアプリケーション開発において、サーバーサイドエンジニアは、アプリケーションのセキュリティを守る上で重要な役割を担っています。サーバーサイドはデータの管理、認証、認可、APIの提供など、アプリケーションの中核を成す部分であり、攻撃者はこの層を狙うことが多いです。セキュリティを強化するためには、サーバーサイドでの適切な設計、実装、監視が不可欠です。

本記事では、サーバーサイドエンジニア向けに、最近のセキュリティトレンドとそれに対する最適な対策を解説します。

---

## 1. APIセキュリティの強化

### 1.1. API攻撃の増加

APIは、クライアントとサーバー間でデータをやり取りするための重要なインターフェースです。特に、認証情報の漏洩や不正なAPIリクエストによるデータ漏洩がリスクとなります。

### 1.2. APIセキュリティのベストプラクティス

- **OAuth 2.0 と OpenID Connect**: 安全な認証と認可を実現。
- **JWT（JSON Web Token）の使用**: 安全なセッション管理。
- **入力検証とサニタイズ**: 不正なデータの注入を防止。
- **レート制限**: DDoS攻撃やブルートフォース攻撃を緩和。

---

## 2. インジェクション攻撃対策

### 2.1. SQLインジェクションのリスク

SQLインジェクションは、攻撃者が不正なSQLコードを注入することで、データ漏洩や改ざんを引き起こす攻撃です。

### 2.2. SQLインジェクション対策のベストプラクティス

- **パラメータ化されたクエリの使用**: Prepared Statementsを活用。
- **ORM（Object-Relational Mapping）の利用**: SQLインジェクションのリスクを低減。
- **データベースの最小権限の原則**: 必要最低限の権限を付与。

---

## 3. 認証と認可の強化

### 3.1. 不正アクセスの防止

認証と認可を適切に実装することが、攻撃を防ぐ鍵となります。

### 3.2. ベストプラクティス

- **二要素認証（2FA）**: パスワード漏洩の影響を軽減。
- **ロールベースアクセス制御（RBAC）**: 必要最低限の権限を付与。
- **JWTの使用**: セキュアなセッション管理。

---

## 4. セキュアなセッション管理

### 4.1. セッション固定攻撃

予測可能なセッションIDを攻撃者が利用して、セッションを乗っ取る攻撃。

### 4.2. ベストプラクティス

- **セッションIDの安全な生成**: ランダムかつ予測不可能にする。
- **HTTPOnly と Secure フラグの使用**: クッキーを安全に管理。

---

## 5. セキュアなデータストレージとバックアップ

### 5.1. データの暗号化

データは保存する前に暗号化し、特に個人情報や機密情報は安全に管理する必要があります。

### 5.2. ベストプラクティス

- **AES-256暗号化**: データの保護。
- **バックアップの暗号化**: 漏洩リスクの軽減。

---

## 6. まとめ

サーバーサイドエンジニアとして、以下のセキュリティ対策を実施しましょう：

- APIセキュリティ（OAuth 2.0、JWT）
- インジェクション攻撃対策（パラメータ化クエリ、ORMの利用）
- 認証と認可の強化（2FA、RBAC）
- セッション管理（安全なセッションID、タイムアウト設定）
- データストレージとバックアップの暗号化

セキュリティ対策は継続的に見直し、改善を図ることが重要です。セキュリティバイデザインのアプローチを採用し、最初からセキュリティを考慮したアーキテクチャを構築しましょう。

---

## 参考リンク：サーバーサイドエンジニア向けセキュリティ対策

1. [OWASP: Open Web Application Security Project](https://owasp.org/)
2. [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
3. [OWASP API Security Project](https://owasp.org/www-project-api-security/)
4. [Security Engineering: A Guide to Building Dependable Distributed Systems](https://www.amazon.com/Security-Engineering-Dependable-Distributed-Systems/dp/1119642781)
5. [Cryptography and Network Security - William Stallings](https://www.amazon.com/Cryptography-Network-Security-Principles-Applications/dp/0134444280)
6. [JWT.io](https://jwt.io/)
7. [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
8. [OWASP ZAP (Zed Attack Proxy)](https://www.zaproxy.org/)
9. [Cloud Security Alliance (CSA)](https://cloudsecurityalliance.org/)
10. [Secure Your APIs: Authentication, Authorization, and Attack Prevention](https://www.coursera.org/learn/secure-apis)
404 Invalid URL (POST /v1/chat/completions/)が直らない

正直こんなことで記事にして良いか迷いましたが、自戒を込めて記事にします。

# 問題

ReactNative/TypeScriptでOpenAIのAPIを使用した際に、`404 Invalid URL (POST /v1/chat/completions/)`が直らない問題に直面しました。

試したことは以下です。
- AuthorizationでAPIキーが適切にheaderに渡せているか
- モデル名（`gpt-4o`, `o1`など）が適切か（https://platform.openai.com/docs/models）
- メッセージは適切か

それでもエラーが直らず、四苦八苦していました。

が、まさかのBillが0だったことが原因でした。
# なぜこんなことが起きたか

クレジット購入日は2023年11月（Dec 2024は原因が判明後買い足したものです）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376078/2bcf990a-6154-fc97-ad04-9c64a78e8de1.png)


しかしなんと、一年たったらExpiredされていたのです（Dec 01, 2024は原因が以下同文）。

![image(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376078/5bceeb88-e012-468a-8d79-ac8375b16dee.png)

え〜、一年でなくなるなんて書いてなくね〜？PricingのFAQ確認したよ〜？

と思ったが束の間、ポリシーに書いてありました。しかも太字で。（さすが訴訟大国アメリカ）

> **All sales of Services, including sales of prepaid Services, are final. Service Credits are not refundable and** **expire one year after the date of purchase or issuance if not used, unless otherwise specified at the time of purchase**. - (https://openai.com/policies/service-credit-terms/)
> 

（訳）プリペイド・サービスの販売を含め、本サービスの販売はすべて最終的なものとなります。 サービスクレジットの払い戻しはできず、購入時に特に指定がない限り、未使用の場合は購入日または発行日から1年後に失効します。

こんなこともあるので、コードは絶対合ってる自信があるのに404が出る方、念の為Billも確認してみてくださいね。
米田の補題 #20 モノイド準同型

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# モノイド準同型

圏のところで、モノイドがでてきました。圏においてモノイドは対象ひとつであることが強調されます。モノイドは代数構造で、内部は、圏の定義を満たしているようなものです。モノイド同士の関係は、圏と圏との関係とよくにていて、関手が容易に導入できます。
数学的にはモノイド準同型ばかり扱うので、素朴な圏と圏の間の関手が具体的な考察対象になることは少ないでしょう。でも、**このAdventCalendar は、米田の補題をプロジェクトマネジメントに応用**することを目的としています。数学的な世界から借りる発想はごく簡単ものにとどめます。

準同型は、いいことあるのでしょうか？　数学的になるとなにそれおいしいというがピンとこないですね。
そこで、ものすごく単純な対象が３つの自然数[0,1,2]で考察しましょう。加法を、足して３で割ったあまり（mod 3)にすれば、モノイドでもあり、圏でもあると言い張れるでしょう。これと対応する圏は、[5.1,6.2,10.01]とします。関手の条件は、最初からみたしているかは、不明（気にしないで）で議論をすすめます。
さて、対象の対応は、0->5.1、1->6.2、2->10.01 とします。これは、全単射の事例なので、かなり厳しい条件になっていますが、気にしません。自然数の場合は、１の次は自明です。一方、[5.1,6.2,10.01]の場合は、6.2の次は自明とはいえません。対応づけると6.2 の次は、10.01が自明になります。実際の作業はソートです。自然数でない数の集合も、ソートすると自然数と同じ構造になります。自然数は、加法について、可換でもあり、非常に強い条件設定になっています。1 + 2 は、2 + 1 と同じです。自然数は、単なるモナイドではなく可換モナイドです。可換モナイドは、数、数量、ベクトル（座標）など、数的な対象を扱うのに適したものです。なんとなく、そうだなあと思えるでしょうか？　そういった可換モナイド間の関手は、ある可換モナイドの構造を他の可換モナイドに見出して、便利です。イベントの受付で、ネームタグを名前を読みの順番で並べるのはよく行われています。自然数を対象とする関手は並べ替えそのものともいえます。関手的な発想がなんかやくにたちそうな気がしませんか？

**米田の補題川柳　数えればすごく便利だ当たり前**
数学的には、可換モナイドは非常に便利ですが、企画進行には、単純で使いやすいものがいいです。可換はなくてよいですし、対象の数は、４までがいまのところよいと思っています。五次方程式がとけないので、なんとなく納得しています。対象の圏の内部構造は、自然数との対応にします。但し、自然の構造が関手経由でほとんど、うつらくてもよいとします。ただ、連番ふるだけです。つまり、圏は[0][0,1],[0,1,2],[0,1,2,3] いずれかと準同型で考えます。企画進行で一度に考察するのは、対象４つが限界です。実際、会議で説明がよく行われますが、対象１の事例です。いろんな説明（内部構造を持つ射）があるので、説明と説明の間に関手を導入して簡素化する必要はよくあります。それが、難しいと言われるモナドです。モノイドの自己関手です。
企画進行は、大風呂敷を広げておいて、対象や対象間の射を関手を経由して減らしていく過程とも考えられます。大風呂敷を広げて最初に企画対象の課題を網羅的にリストアップする前提ではありますが
米田の補題 #19 hom関手

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# hom関手

圏論には、hom集合とか、hom関手と聞き慣れない言葉がでてきます。言葉を割り当ているのは面倒なので、矢印の向きを反転させた圏Cを、
$$
{\LARGE C_{\small op}}
$$
のように書いたりします。複雑な概念を短く記述するのは、複雑な概念に対する共通認識ができていると便利です。でも短く記述した概念の意味が共有されていないと議論でおいてぼりになる人が続出です。チケット #58 の解決方法は、子チケットの#105 に書いてあります。とか、中身が共有されていないと困ります。
hom なんとかは homomorphism 準同型写像の略です。少しは、すわりがよくなったでしょうか？　実際によく使うもは、こんな記法です。
$$
{\LARGE Hom_{\small c}(A,B)}
$$
直感的にわかりにくいですよね。意味は圏CにおけるAからBへの射の全部の集合という意味です。関手も射ですから、hom集合でもいいのですが、hom関手とよびます。想像する図式は射が複数のびているのを思い浮かべましょう
```mermaid
---
title: 圏の場合、複数の射の集合
---
graph LR;
a[域]-.->|射1|b[余域]
a[域]-.->|射2|b[余域]
a[域]-.->|射3|b[余域]
```
射は全部違うものです。これが実は**超重要**です。射１と射２が判定できるからです。現実世界で考えると良品と不良品を判定することそう簡単にできないことが多いです。

**#米田の補題川柳 hom関手hom集合おぼえよう**
射全体を集合とみなすことはしばしば行われます。しょうがないので記法は覚えましょう。暗記も重要です。
プロパティの後ろにつく?は何を意味しているのか？

Typescriptで開発していると、以下のようなコードに出会うと思います。

```typescript
const resultText = data.choices[0]?.message?.content?.trim();
```

プロパティの後ろにつく`?`は何気なく使っていましたが、実際何なのよってことでまとめます。

公式では以下。
> **オプショナルチェーン (`?.`)** (optional chaining) 演算子は、オブジェクトのプロパティにアクセスしたり、関数を呼び出したりします。この演算子を使用してアクセスするオブジェクトまたは呼び出される関数が [`undefined`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined) または [`null`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/null) の場合、エラーが発生することなく、式が途中で終了し、[`undefined`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined) と評価されます。
> 

https://www.typescriptlang.org/docs/handbook/2/objects.html#optional-properties


オブジェクト内のプロパティがあるかどうか判定し、なければ`undefined`を返してくれる優れもの。
# オプショナルチェーンの役割
安全なプロパティアクセスを保証したいときに使います。
- ネストされたプロパティ（choices[0].message.content など）を直接参照すると、途中でオブジェクトが null や undefined の場合にエラー（TypeError: Cannot read property ...）を回避する。
- プロパティが存在しない場合でもエラーを投げず、安全にundefined を返す。

# 動作例

ケース 1: 正常なデータ

```csharp
const data = { choices: [{ message: { content: " Hello World " } }] };
const resultText = data.choices[0]?.message?.content?.trim(); // "Hello World"
```

ケース 2: プロパティが欠けている場合

```csharp
const data = { choices: [{}] };
const resultText = data.choices[0]?.message?.content?.trim(); // undefined
```

ネストされたオブジェクトやメソッドの安全なアクセスを簡単にする便利な演算子です。コードを簡潔にし、予期しないエラーを防ぐため、ぜひ活用してみてください！
フロントエンドエンジニア向け2024年のセキュリティトレンド

![マインドマップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/adf72839-fefa-4cb4-fb4a-7211ebacef56.png)


## 2024年のWebアプリケーションセキュリティの必須知識

Webアプリケーションのフロントエンド開発は、ユーザーと直接接する部分であるため、セキュリティにおいて特に重要な役割を果たします。攻撃者は、しばしばフロントエンドの脆弱性を利用して不正アクセスを試みるため、エンジニアは最新のセキュリティトレンドを理解し、対策を講じることが求められます。

本記事では、フロントエンドエンジニア向けに最近のセキュリティトレンド、対策方法、そしてセキュリティ強化のために今日から実践できるアクションプランを紹介します。

---

## 1. クロスサイトスクリプティング（XSS）対策

### 1.1. XSS攻撃の概要

クロスサイトスクリプティング（XSS）は、攻撃者が悪意のあるスクリプトをWebページに挿入し、ユーザーのブラウザで実行させる攻撃です。これにより、セッションの乗っ取りや、ユーザーの機密情報を盗むことができます。

### 1.2. XSS対策のベストプラクティス

- **コンテンツセキュリティポリシー（CSP）**: 信頼できるソースからのみスクリプトを実行することで、XSS攻撃を防ぎます。
- **HTMLエスケープ**: ユーザー入力を表示する際にHTMLエスケープを行い、スクリプトが実行されないようにします。
- **モダンなフレームワークの活用**: ReactやVueなどのフレームワークは、DOM操作の安全性を確保する仕組みを提供しています。

---

## 2. クロスサイトリクエストフォージェリ（CSRF）対策

### 2.1. CSRF攻撃の概要

CSRF（Cross-Site Request Forgery）は、ログイン中のユーザーに意図しないリクエストを送信させる攻撃です。これにより、ユーザーの権限が不正に利用される可能性があります。

### 2.2. CSRF対策のベストプラクティス

- **CSRFトークンの使用**: サーバーが発行する一意のトークンをリクエストに含めることで、不正リクエストを防止します。
- **SameSite Cookie属性**: クッキーに`SameSite`属性を設定し、外部サイトからのリクエストにクッキーを送信しないようにします。

---

## 3. セキュアなデータの取り扱い

### 3.1. データの保護

フロントエンドで扱うデータ（個人情報や機密情報）は、保存、送信、受信のすべての段階で保護する必要があります。

### 3.2. セキュアなデータの取り扱い方法

- **HTTPSの強制**: Webサイト全体でHTTPSを使用して通信を暗号化します。
- **敏感なデータの暗号化**: サーバーでデータを暗号化し、フロントエンドでは機密情報の保存を避けます。

---

## 4. セキュリティ・バイ・デザインのアプローチ

### 4.1. セキュリティの初期設計段階での考慮

セキュリティは「後から追加するもの」ではなく、開発の最初から設計に組み込むべきです。

### 4.2. セキュリティを組み込むための方法

- **最小権限の原則**: 必要最小限の権限でユーザーを運用。
- **コード監査の実施**: 開発プロセスの早い段階でセキュリティレビューを行います。

---

## 5. まとめ

フロントエンドエンジニアとして、セキュリティ対策を意識することは非常に重要です。特に、以下のアクションを今日から実践することが求められます：

- **コンテンツセキュリティポリシー（CSP）を実装**
- **入力データのエスケープと検証**
- **HTTPSの強制**
- **セキュリティ・バイ・デザインの意識**

セキュリティは継続的に意識して取り組む課題です。これらのセキュリティ対策を徹底することが、ユーザーの信頼を守り、Webアプリケーションを安全に保つ鍵となります。

---

## 参考リンク：フロントエンドエンジニア向けセキュリティ対策

1. [OWASP: Open Web Application Security Project](https://owasp.org/)
2. [OWASP Cheat Sheet Series: Cross-Site Scripting (XSS)](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_(XSS)_Prevention_Cheat_Sheet.html)
3. [Content Security Policy (CSP) - MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
4. [Google Developers: Web Fundamentals - Security](https://developers.google.com/web/fundamentals/security)
5. [Security Headers](https://securityheaders.com/)
6. [JWT.io](https://jwt.io/)
7. [React Security Best Practices](https://www.smashingmagazine.com/2021/06/react-security-best-practices/)
8. [OWASP ZAP (Zed Attack Proxy)](https://www.zaproxy.org/)
9. [Web Security Academy - PortSwigger](https://portswigger.net/web-security)

---
v0で開発補助ツールを作る方法

最近v0で開発補助ツールを作るのにハマっているので、検証ついでにどのように作成しているか紹介します。

https://powerplatformnikki.com/powerautomatesupporttool  

https://powerplatformnikki.com/powerappssupporttool

## v0とは

```
v0は、Vercelによって作成されたAIコーディングアシスタントです。主な特徴は以下の通りです：

1. 最新の技術とベストプラクティスに常に精通しています。
2. React、Next.js App Router、そして最新のWeb開発に特に強みがあります。
3. ウェブ開発に関する質問に答えたり、コードの例を提供したりすることができます。
4. チャットのようなウェブインターフェースを通じてユーザーとやり取りします。
5. コードの例や説明を提供する際には、プレビューとコードエディタを備えた特別なブロックを使用します。


v0は、開発者がモダンなウェブアプリケーションを構築する際の支援を目的としており、特にVercelのプラットフォームとの統合に優れています。
```

せっかくなのでv0自身に説明してもらいました。Claude 3.5 Sonnet Artifactsでも可能なコード生成に特化したツールです。

## 作り方の例：Power Automateのフローをコピペで使えるようにするボタン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/efe7e866-5091-fbf0-5632-4950ac66e97d.png)

v0に上記のようなプロンプトをフローの定義をコピペして投げることで、以下のようなボタンを生成してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/bd564e16-9b56-81a0-1363-bcf5e19a65e3.png)

もちろん一発で思い通りのものが生成されることはほとんどないので、以下を繰り返すことで想定通りの動作をするものを作成します。

1. プロンプトを投げて生成されたものを実際の環境で実行してみる  
2. テストをして、不具合や修正してほしい箇所をプロンプトに含める  
3. 上記をプロンプトを適宜見直しながら繰り返す  

## 実演：Power Appsの編集フォームのコントロール置換

前からアイデアだけはあったものを年末年始で作る予定なので、今回はその検証をしてみます。

### 概要

概要としては、編集フォームのスタイル変更やコントロールの変更をボタンを押すだけで一括処理するものです。

フィールド数が多くなるとPower Apps Studioが重くなってしまい、なおさら変更に時間を要すのでツールで一括変更をしたいです。

### 要望と想定される入出力をプロンプトに含める

検証なので1項目に絞っていますが、以下のようにコンボボックスになっているものをラジオボタンでの入力に置換するものを想定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/abd023ad-5899-f6e5-1d74-ed95feb6e33f.png)

Power Appsのコードビュー機能でYamlテキストをコピーして以下のプロンプトで生成を依頼してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/b7139ff1-72ca-83c1-85e5-80d08ea031e5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/99dd5150-a8ba-0f03-ffb1-c19fa9e18926.png)

すると以下のようなフォームが生成されたので実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/db79446f-2116-8318-44dd-e1dfcaefd1cb.png)

コードでペーストできる形式ではありましたが、想定通りの形式で変換はされませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/745055a7-e9b5-1bfc-655f-f6de0965f073.png)

以下のように再度想定結果と実際の結果を比較させるなどして、想定通りの動作をするまで調整します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/7fd6500c-84eb-0587-3ed2-024897552948.png)

https://www.youtube.com/watch?v=ViPAmJRR8H0

…何度か試してみましたが、上限が来てしまったのでいったん諦めました。  
複雑なこと(今回は特にトークン数が多いので難しいと推察)やろうとすると普通にコードを書いた方がやっぱりいいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/e5029ac2-9b59-0448-3d73-3909e4ecc023.png)

年末年始にはこのナレッジを活かしてコントロールの書式コピーツールとか作ろうと思います。  
それでは、よいお年をお迎えください。

## 元記事

https://powerplatformnikki.com/v0devsupporttool/
ScanSnapでWi-Fiアクセスポイントが見つからないなら、チャンネルを見よう

先日、[ScanSnap iX100](https://www.pfu.ricoh.com/scansnap/products/ix100/)を購入しました。

ScanSnapのお陰で、家に溜まっていたレシートの山があっという間に片付いて、助かりました。

しかし、ScanSnapで一つ悩みがありました。

# Wi-Fiに接続できない

PCでScanSnapのWi-Fi設定で、自宅のWi-Fiアクセスポイントが見つかりませんでした。

他の端末では問題なく表示、接続できていました。

とにかく公式のヘルプページを確認してみました。

> ［注意事項］
> ・無線ルーター側のネットワーク名（SSID）のセキュリティ種別が「WPA3」固定の場合は、iX1300/iX100を接続できません。「WPA2」に接続してください。
> 
> ・「iX100」は、2.4GHzのネットワーク名（SSID）に対応しています。
> ※5GHzのネットワーク名（SSID）は非対応です。   

https://faq.pfu.jp/faq/show/5591?back=front%2Fcategory%3Asearch&category_id=141&commit=&keyword=iX100&page=1&site_domain=scansnap&site_id=2&sort=sort_keyword&sort_order=desc

色々と原因探りをしてみましたが…

- SSIDは2.4GHz対応のものを選んでいる（が、ScanSnapのWi-Fi一覧には出てこない）
- セキュリティーキーに誤りはない
- セキュリティ種別はWPA3/WPA2に設定している
- ScanSnapのファームウェアは最新だった

どれも、原因解決とはなる手がかりとはなりませんでした。

# ネットワークアナライザーで検証してみた

スマートフォンのネットワークアナライザーアプリで、Wi-Fiが使用しているチャンネルをチェックしてみました。

自宅のWi-Fiは混線しないように、13chにしていました。

Wi-Fiチャンネルについて色々と調べたところ…

> 2.4Ghz帯の周波数帯は、日本国内で利用できるチャンネル数が14個ですが、1つのチャンネル幅が規格上22Mhzであるため、11b/gで干渉なしで通信できる最大チャンネル数は4個です。
チャンネル設計としては、1ch・6ch・11ch・14chですが、14chに対応しない機器も多く、その場合、チャンネル数は3個です。
規格より狭いチャンネル幅で通信し、1ch・5ch・9ch・13chの計4チャンネル同時利用を行える機種もあります。

https://www.hitachi-solutions.co.jp/aruba/recommend-contents/guide/channel.html

13ch,14chあたりだと対応しない機器があるとのことでした。

# Wi-Fiのチャンネルを変えてみる

Wi-Fiのチャンネルを13chから11chへと変更してみました。

そしてScanSnapのWi-Fi設定で確認してみたところ…。
ありました。

問題なく接続できました。

# 機器によってはチャンネルが対応していないという教訓

こうしてWi-Fiに繋がらなかったという原因が解決され、ScanSnapの初期不良や不具合ではなかったことに安堵しています。

発売してからしばらく経つ機器が、Wi-Fiのチャンネルに対応していないことがあるようですので、そのような機器を繋げる場合で、繋がらないことがあったら、Wi-Fiのチャンネル設定をチェックしてみてください。
BitriseでGooglePlayConsoleにアプリをアップロードする（事前設定編）

## はじめに
この記事でははじめてBitriseを使用してGooglePlayConsoleにアプリをアップロードする際の手順を説明していきます。
1度設定が完了するとその後は基本的に変更することはありません。


大きく分けて3つの設定があります。
1 GoogleCloudプロジェクトの設定
2 GooglePlayConsoleの設定
3 Bitriseの設定

GoogleCloudプロジェクト↔︎GooglePlayConsole↔︎Bitriseの連携が完了するとBitriseでGooglePlayConsoleにアプリをアップロードすることができます。

ドキュメントを元に実際に作業した手順を説明していきます。
Bitriseの公式ドキュメントの手順
https://devcenter.bitrise.io/ja/deploying/android-deployment/deploying-android-apps-to-bitrise-and-google-play.html

### GoogleCloudプロジェクトの設定
1. Google PlayAPIアクセスの設定
    Google PlayAPIを有効にします。既存のプロジェクトがある場合は、そちらで有効にしても良いですが
    弊社では新規でAndroid用のプロジェクトを作成して、GooglePlayAPIを有効にしました。

2. Google Cloudプロジェクトでサービスアカウントを作成する
    - a.まずはIAMの権限をONにする
    https://cloud.google.com/iam/docs/keys-create-delete?hl=ja
    
    
    
    - b.サービスアカウントを新規で作成する
    https://console.cloud.google.com/projectselector2/iam-admin/serviceaccounts?hl=ja&inv=1&invt=AbkPVg&supportedpurview=project
    
    ![スクリーンショット 2024-12-16 12.09.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624617/407392df-b25a-8eac-58cf-1198350c7ce3.png)


### GooglePlayConsoleの設定
ユーザーと権限で2の工程で作成したサービスアカウントを新規で招待します。
これにより、GoogleCloudプロジェクトとGooglePlayConsoleの連携が完了です。
https://play.google.com/console/u/0/developers/users-and-permissions?hl=ja
![スクリーンショット 2024-12-16 12.04.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624617/174cff78-a452-f650-e5f0-9561a4affef3.png)



### Bitriseの設定
1. 署名キーなどのアップロード設定
 ![スクリーンショット 2024-12-16 12.24.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624617/30182191-b4cd-8f07-5ba0-0b65395dfeac.png)


2. ワークフローの作成
    - Service Account JSON key file path
    作成したサービスアカウントのJSONキーをアップロードし、パスを指定します。
    - Package name
    ビルド対象のパッケージ名を入力します。
    事前にProject Environment Variablesで設定している場合は選択するだけでOKです。
    - App file path
    署名済みのAPKまたはAABファイルのパスを指定します。
    - Track の設定
    アプリを配信するトラックを選択します：
      - internal: 内部テスト
      - alpha: クローズドテスト
      - beta: オープンテスト
      - production: 製品版リリース

その他の項目はデフォルト設定のままで問題ありません。


ビルドを実行し、GooglePlayConsoleビルドしらアプリが配信されていれば成功です！
今後はBitriseから簡単にアプリをアップロードできるようになります！
SAMLについてまとめる

## はじめに
SAMLについてあまりよくわかっていなかったため、記事にまとめました。

## シングルサインオン（SSO）とは？
SAMLが何かを述べる前に、シングルサインオン（SSO）について簡単にまとめます。

SSOは、ユーザーが1度認証を行えば複数のアプリケーションやサービスを利用できるようになる仕組みのことです。

この仕組みを利用することで、ユーザーはアプリケーションやサービスごとのログイン情報を管理する必要がなくなるので、利便性やセキュリティが向上します。

## SAMLとは？
[こちらのページ](https://arc.net/l/quote/tjsnznew)から引用すると、SAMLは以下のようなものを指します。
x
> SAMLとは、Security Assertion Markup Languageの略称であり、OASISによって策定された異なるインターネットドメイン間でのユーザー認証を実現するXMLベースの標準規格です。

「異なるインターネットドメイン間でのユーザー認証を実現する」とありますが、すなわちSAMLはSSOを実現するための標準規格と言い換えることができます。

## SAML認証の仕組み
### 用語の確認
#### サービスプロバイダ（SP）
認証済みのユーザーに、アプリケーションやサービスを提供するシステムを指します。

具体例：Slack, Figmaなど

#### アイデンティティプロバイダ（IdP）
アプリケーションやサービスを利用するために必要な認証情報（SAMLアサーション）を提供するシステムを指します。

具体例：Okta, Google Workspaceなど

#### SAMLアサーション
IdPが生成する認証の結果などのデータのことを指します。このSAMLアサーションいは、認証の結果やユーザーの情報などが含まれます。

### 認証の種類
#### SP Initiated
SP Initiatedは、SP起点のSAML認証です。利用したいアプリケーションやサービス（SP）にアクセスから始まるので、わかりやすい認証フローになっています。

##### 認証フロー
1. ユーザーがSPにアクセスする
1. SPがIdPにリダイレクト
1. IdPで認証を行う
1. IdPがSAMLアサーションをSPに送る
1. SPがSAMLアサーションを検証する
1. アクセスが許可される


#### IdP Initiated
IdP Initiatedは、IdP起点のSAML認証です。SP Initiatedとは違い、IdPにアクセスしてから利用したいアプリケーションやサービス（SP）にアクセスします。

##### 認証フロー
1. ユーザーがIdPにアクセスする
1. IdPで認証を行う
1. ユーザーがSPを選択する
1. IdPがSAMLアサーションをSPに送る
1. SPがSAMLアサーションを検証する
1. アクセスが許可される

## 参考にした記事
- [シングルサインオン（SSO：Single Sign On）とは？意味・定義 | IT用語集 | docomo business Watch | ドコモビジネス | NTTコミュニケーションズ 法人のお客さま](https://www.ntt.com/bizon/glossary/e-s/sso.html)
- [SAML認証ってなんやねん](https://zenn.dev/mi_01_24fu/articles/saml-2024_04_01)
- [SAMLとは？SSOを実現するSAML認証の仕組みやメリット・デメリットを解説 | 統合認証・アクセス管理ソリューション | 日立ソリューションズ](https://www.hitachi-solutions.co.jp/iam/saml.html)
!==について

JavaScriptやTypeScriptを使っていると、普段から使い慣れた演算子である!=。ある日、chatGPTが!==という記号を提示してきたとき、「これはタイプミスか⁇」と戸惑ったことがありました。しかし調べてみると、「厳密不等価」という比較演算子であることが判明。

https://jp-seemore.com/web/13411/

今回は!==の意味と使い方について解説します。

# **!==とは⁇**

JavaScript（およびTypeScript）では、!==は「厳密不等価演算子（strict inequality）」を表します。この演算子は以下のように動作します。

- 値 **および型** が異なる場合にtrueを返す
- それ以外の場合はfalseを返す

一方、!=は「不等価演算子（inequality）」と呼ばれ、型変換を行った上で値が異なるかを判断します。

# **!==と!=の違いを比較**

コード例で違いを見てみましょう。

```tsx
*//* 不等価演算子 *(!=)*
console.log(5 != "5"); *// false (値が同じなので等価と判断)
// 厳密不等価演算子 (!==)*
console.log(5 !== "5"); *// true (型が異なるため不等価と判断)*
```

上記の例からわかるように、!=は型を無視するため、5と"5"を同じものと見なします。一方、!==は型まで考慮するため、より厳密な比較が可能です。

# **chatGPTのコード提案で遭遇**

React Native/TypeScriptで開発しているとき、以下のようなコードでchatGPTが提案してきました。

```tsx
if (userId !== undefined) {
	console.log("User ID is defined.");
}
```

最初は「!=で十分では⁇」と思いましたが、!==を使うことで、nullとundefinedを区別するときに使用できることが判明。

```tsx
const userId = undefined;
console.log(userId != null);  // false (型変換される)
console.log(userId !== null); // true  (厳密に比較される)
```

この挙動のおかげで、バグの原因となる曖昧な条件判定を避けることができた（はず）。

※undefinedもnullも「データがない」ことで共通していますが、undefinedは「値が未定義」、nullは「値が意図的に空」の状態。Redditにわかりやすい画像があったので添付。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376078/d65aa6be-ceb9-be58-f6f1-1a306c1a0838.png)
(https://www.reddit.com/r/ProgrammerHumor/comments/f03mhi/null_undefined_0/)

# **なぜ!==を使うべき⁇**

React NativeやTypeScriptでは、特に型安全性が重視されます。

それに、どんな言語を使っていても予期せぬ挙動は避けたいですよね。不用意にリスクを増やさない、他のエンジニアに意図が伝わるなどメリットが多いので、使える場面はなるべく使っていきたいですね。
米田の補題 #18 関手の例  反変関手

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# 関手の例 反変関手
前回は、対象が２つしかないとしかも射の方向性が一方通行にして、射をひとつに限定して合成も無視しましたが、今度は、逆方向も考慮します。すると射は２つになるので、射の合成も考慮できます
少しづつ、米田の補題に近づけて理解するようにします。関係の矢印は、向きが逆のこともありますね。Aは、Bが好き　とBは、Aが好きでは、向きが逆です。圏Cについて、矢印を全部反転させた圏を考えましょう。これも圏になります。ある圏を想定すると、構造の似た圏を**どんな圏**に対しても想定できるのです。
C にop（反対の意味のoppositの略op）をつけて書きましょう。
$$
{\LARGE C^{\small op}}
$$
関手の定義では、合成が移ります。移るときに、順番がひっくりかえるF(f∘g) = F(g)∘F(f)場合はこの定義によく似ています。でも残念ながら、これでは、関手の定義からはずれてしまいます。説明をしませんが、関手の定義を満たしていると、いろんな定理が証明できます。それで、これも関手だとしたいのです。
$$
{\Large 圏Cのかわりに}
{\Large 圏C^{\small op}を使えば、通常の関手になります}
$$
このようになっている関手を**反変関手**といいます。通常の関手と区別するために、**反変関手**と呼ぶのです。通常の関手は、区別するために**共変関手**と呼ぶこともあります。
圏で、矢印の向きが逆の射を個別にひとつひとつ導入するのはもちろんできます。でも一括で全部ひっくりかえして、関手で考えると簡単になります。圏の内部構造を意識しないすみます。内容はよくわからないけど、矢印は全部逆になっていることがわかれば、関手として扱えるのです。**関係は内容よりも重要だ**の米田の補題川柳がなんとなくわかってきませんか？

**米田の補題川柳 逆むきは一括ならば簡単だ**
内部構造を細かく意識しないでも、全部反転しているとすれば、便利なことがあります。作業工程のチェック一つ前まで全部検証する場合です。圏と考えることができます。矢印が逆ですが、反変関手にして、対象や、射を減らせます。つまり検査項目の省略を図式にするとき役立ちそうな気がしませんか
セキュリティー分野でのキャリアパス

![マインドマップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79373/39bbd014-c8d3-5d72-e22c-a644d5e3e3e9.png)



### エンジニアやコンサルタントの進路

サイバーセキュリティは、急速に進化する分野であり、その需要は今後ますます高まることが予測されています。個人の情報や企業の機密情報を守るために、セキュリティの専門家が不可欠となっています。エンジニアやコンサルタントとしてセキュリティ分野でキャリアを築くには、どのような進路を歩むべきか、またどのようなスキルや資格が求められるかを理解することが重要です。

本記事では、セキュリティエンジニアやセキュリティコンサルタントとしてのキャリアパスを紹介します。

---

## 1. セキュリティエンジニアとしてのキャリアパス

セキュリティエンジニアは、企業のネットワークやシステムを守るための技術的な側面を担当する専門職です。この職種では、攻撃者からの脅威を予測し、システムの脆弱性を最小限に抑えるために多くのスキルと経験が求められます。

### 1.1. セキュリティエンジニアの基本的な役割

セキュリティエンジニアは、以下のような業務を担当します：

- **ネットワークとシステムの監視**: 不正アクセスや攻撃を検出し、迅速に対応。
- **脆弱性の評価とテスト**: システムやアプリケーションのセキュリティテストを実施し、潜在的なリスクを特定。
- **セキュリティツールの管理**: ファイアウォール、IDS/IPS、暗号化ツールの導入・管理。
- **インシデント対応**: セキュリティインシデント発生時の原因特定と被害の最小化。

---

### 1.2. セキュリティエンジニアとしてのキャリアステップ

1. **ジュニアセキュリティエンジニア**:
   - 基礎スキルを学びながら実務経験を積む。
   - 基本的なツールや技術を習得し、インシデント対応に従事。

2. **ミッドレベルセキュリティエンジニア**:
   - より高度な攻撃手法や防御策を理解。
   - セキュリティポリシーの改善や、複雑なシステムのセキュリティ強化を担当。

3. **シニアセキュリティエンジニア**:
   - 組織全体のセキュリティ戦略を策定し、チームをリード。
   - 高度な脅威の分析やセキュリティアーキテクチャの設計を担当。

---

### 1.3. 必要なスキルと資格

- **ネットワークセキュリティ**: TCP/IP、VPN、ファイアウォールの知識。
- **プログラミング**: Python、PowerShell、Bashのスクリプト作成スキル。
- **資格**:
  - Certified Information Systems Security Professional (CISSP)
  - Certified Ethical Hacker (CEH)
  - CompTIA Security+

---

## 2. セキュリティコンサルタントとしてのキャリアパス

セキュリティコンサルタントは、企業のリスクを評価し、最適なセキュリティ戦略を提案する専門職です。

### 2.1. セキュリティコンサルタントの基本的な役割

- **リスク評価**: 脅威や脆弱性の特定。
- **戦略の策定**: クライアントに適したセキュリティポリシーやガイドラインを作成。
- **インシデント対応計画**: 緊急時の対応手順を策定し、実行をサポート。

---

### 2.2. セキュリティコンサルタントとしてのキャリアステップ

1. **ジュニアセキュリティコンサルタント**:
   - セキュリティ評価やレポート作成をサポート。

2. **ミッドレベルセキュリティコンサルタント**:
   - 戦略的アドバイスを提供し、クライアント対応をリード。

3. **シニアセキュリティコンサルタント**:
   - 複雑な問題の解決や組織全体のセキュリティ改善を指揮。

---

### 2.3. 必要なスキルと資格

- **リスクマネジメント**: 組織のリスクを評価し、最適な対策を提案。
- **資格**:
  - Certified Information Systems Auditor (CISA)
  - Certified Information Security Manager (CISM)
  - Certified Cloud Security Professional (CCSP)

---

## 3. まとめ

セキュリティ分野でのキャリアには、エンジニアやコンサルタントとしての多様な進路があります。技術スキルや実務経験を積み重ね、資格を取得することで、成長の機会を広げることができます。

---

## 参考リンク

1. [Certified Information Systems Security Professional (CISSP)](https://www.isc2.org/Certifications/CISSP)
2. [SANS Institute](https://www.sans.org/)
3. [Certified Ethical Hacker (CEH)](https://www.eccouncil.org/programs/certified-ethical-hacker-ceh/)
4. [CompTIA Security+](https://www.comptia.org/certifications/security)
5. [Cybersecurity Career Paths and Resources](https://www.cyberseek.org/)
try-catch-”finally”??

プログラミングでエラーハンドリングといえば`try-catch`が基本ですが、実はもう一つのブロック`finally`をご存知でしょうか？`finally`は、エラーの有無に関わらず必ず実行される処理を記述するための便利な構文です。本記事では、`try-catch-finally`の役割と使い方について解説します。

# finallyとは？

`finally`は、`try`ブロック内の処理が成功した場合でも、`catch`ブロックでエラーが発生した場合でも、必ず実行される処理を記述するために使います。

```tsx
try {
    // 実行したいコード
} catch (error) {
    // エラー時の処理
} finally {
    // 成功・失敗に関わらず実行される処理
}
```

# 使い道

用途としては、ファイルのリソース開放が一番イメージしやすいですね。

```tsx
const readFile = () => {
    let fileHandle;
    try {
        fileHandle = openFile("example.txt");
        console.log(fileHandle.read());
    } catch (error) {
        console.error("Error reading file:", error);
    } finally {
        if (fileHandle) {
            fileHandle.close();
            console.log("File closed.");
        }
    }
};
```

try-catchどちらの場合も実行したい処理を書く場合、両方のブロックに書くなんて~~アホなことする~~人はいないと思いますが（多分過去の自分は書いたけど）、finallyを使わないと以下のようになります。シンプルにtry-catchの外に書けばいいだけですね。

```tsx
const readFile = () => {
    let fileHandle;
    try {
        fileHandle = openFile("example.txt");
        console.log(fileHandle.read());
    } catch (error) {
        console.error("Error reading file:", error);
    }
    // finallyの代替コード
    if (fileHandle) {
        fileHandle.close();
        console.log("File closed.");
    }
};

```

じゃあ一つ目と二つ目が一緒ならfinallyがある意味ないんじゃない。。??（しいて言えば可読性が上がる??）と思いましたが、以下の記事を発見。これ以上ないほど分かりやすい説明だったので~~丸投げ~~紹介します。

https://qiita.com/musenmai/items/c6e7af3dd57f0f88db9c

余談ですが、finallyを知ったきっかけがCopilotが提案したコードに出てきたからです。独学者にとって「AIコード生成→動作確認→コードの意味調べ」という流れもありかもですね。
P(A ∩ B) = P(A|B) * P(B) がわからん。条件付き確率

# 同時に起こる確率

- **P(A ∩ B)**: AとBが同時に起こる確率
- **P(A|B)**: Bが起こったときにAが起こる確率
- **P(B)**: Bが起こる確率

例：

- Bが起こる確率が50%（P(B) = 0.5）
- Bが起こったときにAが起こる確率が20%（P(A|B) = 0.2）
※ Bが起きた後だけ考えた確率だからP(A|B)ではB自体の確率は考えない。(Bが後の事象を100％としてる)下図参照


```
P(B) = 0.5
├── Bが起こる（50%）
│   ├── P(A|B) = 0.2
│   │   ├── Aが起こる（10%）
│   │   └── Aが起こらない（40%）
│   └── 1 - P(A|B) = 0.8
│       ├── Aが起こる（10%）
│       └── Aが起こらない（40%）
└── Bが起こらない（50%）
    ├── P(A|¬B)
    └── 1 - P(A|¬B)
```


この場合、AとBが同時に起こる確率P(A ∩ B)は、P(A|B) * P(B)で計算される。つまり、

$$P(A ∩ B) = P(A|B) * P(B) = 0.2 * 0.5 = 0.1$$




# 条件付き確率

上記の公式を変形して、条件付き確率 (P(A|B)) を求める場合、次のようになる： 
$$P(A|B) = \frac{P(A ∩ B)}{P(B)}$$

Bが起こったときにAが起こる確率を求めるために、AとBが同時に起こる確率をBが起こる確率で割る
​
例：
- AとBが同時に起こる確率が0.1（10%）（P(A ∩ B) = 0.1）
- Bが起こる確率が0.5（50%）(P(B) =　0.5)
この場合、Bが起こったときにAが起こる確率P(A|B)は：
$$P(A|B) = \frac{0.1}{0.5} = 0.2$$

## ベイズの定理

1. **条件付き確率の定義（↑の）**：
   $$P(A|B) = \frac{P(A \cap B)}{P(B)}$$

2. **共通事象の確率の表現（変形）**：
   $$P(A \cap B) = P(A|B) \times P(B)$$
   さらに、条件付き確率の定義を使って：
   $$P(A \cap B) = P(A|B) \times P(B) = P(B|A) \times P(A)$$

3. **上記の式を条件付き確率の定義に代入**：
   $$P(A|B) = \frac{P(B|A) \times P(A)}{P(B)}$$

### 全確率の法則を使った分母の展開
P(B)が(P(B) =　0.5)のように既知でない場合はこのように求める必要がある

4. **全確率の法則**：
   $$P(B) = P(B|A) \times P(A) + P(B|\neg A) \times P(\neg A)$$

5. **ベイズの定理の最終形**：
   $$P(A|B) = \frac{P(B|A) \times P(A)}{P(B|A) \times P(A) + P(B|\neg A) \times P(\neg A)}$$

## まとめ
ベイズの定理は次のように表される：
$$P(A|B) = \frac{P(B|A) \times P(A)}{P(B|A) \times P(A) + P(B|\neg A) \times P(\neg A)}$$
【Unity】HotReloadアセットを使って開発効率を上げる

# はじめに
この記事は[Hamster Output Advent Calendar 2024](https://qiita.com/advent-calendar/2024/game_hamster)の23日目の記事です！

実は、10日辺りからアウトプットをするのが厳しくなり...13日以降からはかなり薄い内容が多いんですよね。そして2週間くらい期間を開けたので短い内容でも、多少はマシな記事を書くことができましたが、残念なことに記事にできる内容は全て出し尽くしました。

なので、残り2日分は紹介や雑記になります。最後まで、走り切ると決めているので残り数記事分頑張ります。

今回は有料アセットのHotReloadの紹介です。

https://assetstore.unity.com/packages/tools/utilities/hot-reload-edit-code-without-compiling-254358?locale=ja-JP&srsltid=AfmBOorTn9Zx0GnV4cFu4GScTNWt5roHVDDGfJiNFSisWeim4Ol-KNGf

# 参考にしたリンク

https://zenn.dev/daichi_gamedev/articles/unity-hotreload

https://coacoa.net/assets/hotreload/

# 何ができるのか
・コンパイルの時間を大幅に無くしてくれる
・再生中にソースコードを書き替えることができて、即時に反映してくれる

Unityでスクリプトを作成した時や、クラスの内容を書き替えた時に画像の様にコンパイルが走りますが、HotReloadを導入するとほとんどこれが無くなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588406/26e1c87b-a455-4957-4521-13b105991dcf.png)

つまり神アセットです。

少し見にくいですが、再生中にスクリプトからログを追加したり消したりなどを行っています。

https://x.com/tagawayuuki_/status/1871912973406806237

# デメリット
・コンパイルの時間が全て消えるわけではなく、再生に入る時はコンパイルされる(EnterPlayModeで省略できる)
・値段が高い77$(セールだと半額になる時もある)
・2023年代に出たアセットで割と新しめのアセットなので未知のバグに遭遇するかも
・Unityのバージョンによってはあまり効果がないバージョンもある(最近のバージョンだと少ない気がする)

# 買った方が良いか
コンパイル時間が気になる人や、スクリプトで値を変えたりする人は特に購入がおすすめ！
米田の補題 #17 関手の図式の例

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

 # 関手の図式の例

 圏の内部構造を簡素化して、対象を２つで、射の方向も一方通行にしてしまえば、この図式で十分です。合成が無視できるので、簡単です
 
```mermaid
---
title: 対象が２つの事例　
---
graph LR;
a[域]-.->|射1|b[余域]
a[域]-.->|射2|b[余域]
a[域]-.->|射3|b[余域]
```
```mermaid
---
title: 関手も複数ありますが、対象は2つになります。
---
graph LR;
a[圏C]-.->|関手1|b[圏D]
a[圏C]-.->|関手2|b[圏D]
a[圏C]-.->|関手3|b[圏D]
```
圏C,Dの内部構造がもっと複雑でも、簡素化できますね。

## 関手なにそれおいしいの？
対応という関係のため関手で対象、射を減らせます。企画で複数の選択肢（複数の射）を出して、減らす進行過程にちかいです。しかも、関手は、対象２つしか感がないので、対象を減らす作業が不要です。なんか量子コンピュータで不確実を確実にするのと似ています。よくわからないけど役立ちそうな気がしませんか？

```mermaid
---
title: 解決策２を選択　課題、解決は圏で、解決策は関手です
---
graph LR;
a[課題]-.->|解決策1|b[解決]
a[課題]-.->|**解決策2**|b[解決]
a[課題]-.->|解決策3|b[解決]
```

**米田の補題川柳　関手では射と対象を減らせるぞ**
関手でも簡単な例を想定しましょう。圏でも同様な図式を使えます。こんな単純な図式でも役立つのがこれからだんだんわかります。
try-catch構文とは

アプリ開発を進める中で、予期しないエラーに対処するために「try-catch構文」を使う場面が多々あります。特にReact Nativeのような非同期処理が多い環境では、エラー処理が欠かせませんよね。本記事では、React NativeとTypeScriptを組み合わせた場合の`try-catch`構文の使い方をまとめます。
# try-catch構文とは？
`try-catch`構文は、**エラーが発生する可能性があるコード**を「試しに実行」（try）し、エラーが発生した場合に「キャッチ」（catch）して適切な対処を行うためのものです。

```tsx
try {
    // 実行したいコード		
} catch (error) {
    // エラー発生時の処理
}
```
そのままじゃん。。て感じなので、よく使う事例をみながらメリットを紹介します。
# React Nativeでの具体例
## 例1) APIリクエストのエラーハンドリング

外部APIを呼び出す場合、ネットワークエラーやレスポンスエラーが発生することがあるので、エラー発生時の処理をcatch内に記述。

```jsx
import axios from 'axios';

const fetchUserData = async () => {
    try {
        const response = await axios.get('https://example.com');
        console.log('User data:', response.data);
    } catch (error) {
        console.error('Failed to fetch user data');
    }
};
```
## 例2) JSONのパースエラー

JSONファイルを処理する際に、フォーマットが不正な場合のエラーをcatch。

```jsx
const parseUserData = (jsonString: string) => {
    try {
        const user = JSON.parse(jsonString);
        console.log('Parsed user data:', user);
    } catch (error) {
        console.error('Invalid JSON');
    }
};
```
# `error`について
これまでは`catch(error)`のみの記述でしたが、`catch(error: any)`と記述する場合もあります。

違いは、**errorオブジェクトを参照するかどうか**です。

errorオブジェクトについてはこちら参照（https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error）

なぜerrorオブジェクトの参照に型指定が必要かというと、デフォルトでは`unknown`とみなされるからです。

例）型指定をしない場合

```jsx
try {
    console.log("Hello, world!");
} catch (error) {
    console.error(error.message); // 型エラー: 'unknown'型に'message'は存在しません
}
```

例）型指定をする場合

```jsx
try {
    console.log("Hello, world!");
} catch (error: any) {
    console.error(error.message); // OK: 型が'any'でmessageにアクセス可能
}
```

ちなみに、以下記事によるとコンパイラーオプションの`useUnknownInCatchVariables`を有効にするとerrorが`unknown`型、デフォルトでは`any`型だそうです（未検証。自分の場合特に設定いじってないのに型指定しないとエラーになったのはなんのことやら）。

https://typescriptbook.jp/reference/statements/exception

他に以下の情報も見つかりました。

> TypeScript 4.4から、catchされたエラーはanyからunknownで返されるようになったらしい。
> 

https://zenn.dev/rikako_0516/articles/72f4b8231a7377

いずれにせよ、頭の片隅にあれば対応可能かと思います。
スライスの長さ、容量、ゼロ値

## はじめに

A Tour of Goについて勉強になった箇所をまとめる。

### 長さと容量

長さ：スライスが現在持っている要素の数
容量：スライスが背後で確保している配列のサイズ

```Go
package main

import "fmt"

func main() {
	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s)

	// Slice the slice to give it zero length.
	s = s[:0]
	printSlice(s)

	// Extend its length.
	s = s[:4]
	printSlice(s)

	// Drop its first two values.
	s = s[2:]
	printSlice(s)
}

func printSlice(s []int) {
	fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
// len=6 cap=6 [2 3 5 7 11 13]
// len=0 cap=6 []
// len=4 cap=6 [2 3 5 7]
// len=2 cap=4 [5 7]
```

### 容量を指定しない場合

要素の追加によって長さが容量を超えたとき、新しくより大きな容量を持つ配列を確保し、既存の要素を新しい配列にコピーした後、新しい要素を追加する。
このプロセスが自動的に行われるため、容量の管理を意識する必要がない。

### 容量を指定する場合

容量は要素が追加されるたびに倍増する。これにより、大量の要素を追加する際のメモリ再割り当ての回数を減らし、パフォーマンスを向上させることができる。

### ゼロ値

スライスのゼロ値は```nil```。
```nil```スライスは長さと容量は0

```Go
package main

import "fmt"

func main() {
	var s []int
	fmt.Println(s, len(s), cap(s))
	if s == nil {
		fmt.Println("nil!")
	}
}
// [] 0 0
// nil!
```
米田の補題 #16 関手

# 米田の補題は、圏論でもっとも重要な定理です（繰り返し）
圏論は、数学の基礎理論です。いままで、[万物の理論](https://amzn.to/3ZLmCJH)
といわれていましたが、[数理科学 11月号](https://amzn.to/4iz6NgM)では、なんと　<font color="Red">万物・万事・万人</font>のための数学理論とまでいわれるようになりました
このAdventCalendar は、体験的に圏論の最も重要な定理である米田の補題を体験的に理解してもらうためにかいています

参考にしているのは、[圏論の道案内](https://amzn.to/4iH2Rus)です

# 関手
どんどん数学よりになってきます。普段のビジネスになにそれ役立つの？　状態ではあると思いますが、もう少し我慢してください。すでに圏とほぼ同じの内部構造をもっているモノイドで、準同型を提示しました。少し条件をゆるくして、モノイドの圏よりも広い圏の圏を考えます。そのとき、圏の間の対応を関手（かんしゅ）とよびます。関手は、圏から圏への射とも考えられます。なお対応には、全射、単射、全単射があり、まぎらわしいです。全射、単射、全単射のおかげで同じ対象との間に複数の対応が存在可能で、対応は射としてとりあつかるようになります。
文章で関手を定義してみましょう。tex で図式を書きたいのですが、時間がかかります。それでのちほど、書き換えるときにします。

圏Cから圏Dへの対応Fが次の条件をみたすとき、Fを、関手といいます。対応は、対象と射の両方になります。

- 圏Cの対象と射 x-- f -->y を、圏D の射F(X) --F(f)--F(Y)に対応
- 圏Cの射の合成がF(f∘g) = F(f)∘F(g)
- 恒等射は、F(1x) = 1F(x)

単純化して言葉で理解しましょう。圏Cは、対象が３つしかないと単純化します。その３つは、X,Y,Zとします。X,Y,Zは内部構造をもっていることもあるのですが、モノイドのように無視しましょう。射は、x,y,zの間に複数とりえます。それが、ちゃんと圏Dに対応（移るという言葉がいいのでしょうか？）します。
このとき、複数の射は、対応なので減ってもいいです。
あとは、合成、恒等射が移ります。

モノイドの圏との違いは、内部構造だけで、圏を考えるのと、圏と圏の間の対象と射の対応を導入することで、圏から圏への射とするのです。内部構造のモノイドを圏に置き換えた一般化です

**米田の補題川柳 関手とは射だと思えばいいだけ**
先ほどは圏C、Dの対象を３つを想定しましたが、2つにして合成の条件を簡素化します。私たちは、対象２つa->b でものごとを考えるの多いので、普段の思考にちかくなります。なんかつかえそうだという気がしませんか？そして対象２つ間の射b->aを想定します。とりあえず、恒等射のように対象が同じ射は無視します。
対象の内部構造が、数学では代数的構造も持っている事例を扱うのですが、通常の企画進行は、圏だけでやり切る必要があります。そこで劇的に圏を単純化して、対象２にとどめましょう。
1.対象が１つ、射はいっぱいある、但し、その中に特殊な射である恒等射がある
2.対象が２つ、射はいっぱいある。恒等射は対象ごとに存在して、その対象そのものとする
3.対象が３つは難しいから、とりあえず考えない　関手の定義の合成が無視しやすくなるのでよいです。
もちろん対象が１つの事例でも数学的には非常に面白い事例になります。モノイドを具体例にしないと圏論は抽象的で中身がないといわれる次第です。対象2つの例で、具体事例を考えましょう。関手は対象２つの事例で定義しています。
```mermaid
---
title: 圏Cでは見えることを対象　同じ猫を射にします
---
graph LR;
a[Aに猫が見える]-.->|猫は同じ|b[Bに猫が見える];
a1[Bに猫が見える]-.->|猫は同じ|b1[Aに猫が見える];
```
射ですから、方向性があります。言葉で補足説明するとAが見ている猫はBが見ている猫と同じは、A->B です。B->Aがなりたつ事例です。Aは、1匹の猫しか見えなくて、Bは、その猫と別の猫もみていたら、どうでしょうか？B->A はなりたちませんよね。実際の会議の議論でも、見えてることが異なるのに、同じものだとする議論は不毛です。　この議論では、「Aに猫が見える」は対象なので圏かどうかは、無視できます。
では、圏Dです。
```mermaid
---
title: 圏Dではキーワードを対象　同じを射にします
---
graph LR;
a[Aが使うキーワード]-.->|キーワードは同じ|b[Bが使うキーワード];
a1[Bが使うキーワード]-.->|キーワードは同じ|b1[Aが使うキーワード];
```

関手は、圏を対象とする射です。この場合は、関手は似ているにしましょう。同じを射をしたのと同様に似ているを関手にします。関手の対象は圏です。内部構造があります。それは圏です。関手は圏の構造を対応づけます。A->B,B->Aという圏Cの構造を圏Dに持ち込みます。ただ、この場合は、圏Cは、対象２つ射２つという単純構造で、しかも、圏Cと圏Dは関手がひとつというわかりやすい事例になっています
今はピンとこないと思いますが、普段つかっている知識構造がとりあえず、圏になっていて、その間の関手が設定できれば、見通しがよくなります。数学的には、モノイドという代数構造をよく扱います。それはそれですごいことができます。ただ、普段の企画進行に応用するには、会議での話題で使われるキーワードの知識体系が圏の体裁をとっていて、そこに関手をどのように設定するかになります。関手が設定できれば、準同型とできます。つまり、圏の対象は違っているけど、圏Cと圏Dは似ているとできます。
```mermaid
---
title: 圏を対象　似ているを関手とします
---
graph LR;
a[圏C]--->|似ている|b[圏D];
```
あれ、関手たる射がひとつになって簡単になりましたね。似ているという関手で、A->B,B->Aの圏Cの構造が、圏Cから圏Dに持ち込まれています。システム開発で言えば、「解決法１はロールバックできる点で解決法２」と似ているという会議での発言につかえます。
矢印の方向は、解決法１が解決法２と似ているか、解決法2が解決法1に似ているかで区別されます。ここで、関手が２つあるとして、解決法2が解決法1に似ているも加えてあげるとどうでしょうか？　なんか普段の議論でもつかえそうな気がしませんか？
ReactNativeでOpenAIのAPI呼び出しに詰まった

OpenAIの公式ドキュメントで、以下の呼び出し方が記載されていました。

```jsx
import OpenAI from "openai";
const openai = new OpenAI();

const completion = await openai.chat.completions.create({
    model: "gpt-4o-mini",
    messages: [
        { role: "system", content: "You are a helpful assistant." },
        {
            role: "user",
            content: "Write a haiku about recursion in programming.",
        },
    ],
});

console.log(completion.choices[0].message);
```

しかし、これをReactNative/Typescriptライクに書き換えても、適切に動きません（そもそも書き換えが待ちが和えている可能性も否めないが）。

# 解決策
以下のフォーラムで、ReactNativeのSDKがサポートされていないことが原因と書かれています。

> OpenAI doesn’t offer a dedicated SDK for React Native. To integrate OpenAI’s API within your React Native and Expo projects, you should use direct HTTP requests. - （https://community.openai.com/t/404-invalid-url-post-v1-chat-completions-chat-completions/680371）
> 

（訳）OpenAIはReact Native専用のSDKを提供していません。 OpenAIのAPIをReact NativeやExpoのプロジェクトに統合するには、直接HTTPリクエストを使用する必要があります。

なので、以下のように直接リクエストを投げると期待した挙動になると思います。

```jsx
const completion = await fetch('https://api.openai.com/v1/chat/completions', {
	method: 'POST',
	headers: {
		'Content-Type': 'application/json',
		'Authorization': `Bearer ${Config.OPENAI_API_KEY}`,
	},
	body: JSON.stringify({
		model: 'gpt-4o-mini',
		messages: [
			{ role: 'system', content: 'You are a helpful assistant.' },
			{ role: 'user',
				content: "Write a haiku about recursion in programming."
			},
		],
	}),
});
```

なんとも紛らわしい。。
「知る」は「好き」に繋がる。知るための工夫

こんにちは、ふるすです。

突然ですがみなさん、人やモノなど何かを好きになる瞬間ってどんなときですか？

私はあまり一目惚れをすることがありません。
ではどんなときに好きと感じるかというと「それについて深く知ったとき」です。
この話がどうDevRelと紐づくんだ、と思われるかもしれませんが、最後まで読んでいただけると嬉しいです。

## 「知る」と見え方が全く変わる

私の趣味は美術史の勉強です。
そういうと「なんか難しそう」「美術ってよくわからないんだよね」とよく言われます。

独学ですし、すべての作品に詳しいわけもありません。
展覧会に行ったって、正直見ていてよくわからないもののほうが多いです。
ですがその作品について「知る」ことができたとき、突然「好き」に変わる瞬間があります。

たとえばその作品はなぜ生まれたのか。どんな時代背景でどんな作者によってつくられ、この美術館の所蔵品になるまでにどんな歴史を辿ってきたのか。同じテーマで同じ時代につくられても、まったく違う作品が生まれるのはなぜなのか。
こういったことを知ると、なんでもないように見えていたただの作品が、自分の中の経験や考え、思いとリンクし、急にいとおしく見えてくることがあります。
この瞬間がたまらなく好きで、美術の勉強を続けています。

また、私は幼いころから説明書が好きなこどもでした。
行儀は悪いですが、レトルトのラーメンや冷凍食品を食べるときですら、パッケージの説明を読みながら食べたり、インターネットの使い方を覚えてからは、商品HPの開発者のこだわりを読みながら食べていました。そうするとなんでもなかったしょうゆ味のラーメンがとてつもなくおいしく感じるのです。
なんてちょろいんだと自分でも思うのですが、幸せや楽しいことが一つ増えるのでそれでいいのです。

## 仕事のはなし

さて、私はCOMPANYという自社製品が好きです。
なぜなら、コンサル時代にこの製品でお客様の業務が改善され、喜んでいらっしゃる瞬間を何度も目の前にしてきたからです。

そしてそのCOMPANYを開発し維持しているのが開発部門です。
開発部門の魅力を社内外に伝え、仲間を増やし、さらにその仲間の満足度を高めることは製品や会社の魅力アップにもつながります。

いい製品やサービス、働く環境があっても「知る」きっかけや手段がなければ伝わらない。そのきっかけや手段作りをするのが私の仕事なんだと思っています。

## 知るためにできること
さいごに、知るために普段意識していることを共有して終わりにしたいなと思います。

**・できるだけ自分でそのものを見ること**
難しく書いてしまいましたが、誰かの意見に流されず、バイアスをかけずに自分が見たままを感じて知ってみるのが大事かなと思っています。

**・違和感がある、苦手なものほど調べてみる**
私の中で、「違和感がある」ということは「知らないからそう感じるんだ」と前向きに捉えています。食わず嫌いせずにまずは知る努力をしてみて、それでも苦手なら私には合わなかったのだと意識の対象外から外しています。

ここまでお読みいただきありがとうございました！
react-native-dotenvとreact-native-configの違い

ReactNativeでモバイルアプリを開発していると、環境変数を管理するために`react-native-config`か`react-native-dotenv`、どちらかのライブラリを検討することになると思います。

本記事ではそれぞれの違いや特徴、使い道などについてまとめます。

# 両者の概要

1. react-native-config
    
    > Module to expose config variables to your javascript code in React Native, supporting iOS, Android, macOS and Windows. - (https://www.npmjs.com/package/react-native-config)
    > 
    
    （iOS、Android、macOS、Windowsをサポートし、React Nativeのjavascriptコードに設定変数を公開するモジュールです。）
    
    メリット:
    
    - ネイティブコードと統合しやすい（info.plist や build.gradle で使用可能）
    - クライアントバンドル内のコードに直接含まれないため、環境変数をある程度秘匿可能
    - ビルドターゲットごとに異なる .env ファイルを使用可能（例: 開発・本番環境）
    
    デメリット:
    
    - 初期設定が若干複雑
    - 動的に環境変数を切り替えたい場合には不向き
    - Web環境との互換性が低い
2. react-native-dotenv
    
    > This babel plugin lets you inject your environment variables into your Javascript environment using dotenv for multiple environments. It is best suited for use with react native and works with all flavors including web. - (https://www.npmjs.com/package/react-native-dotenv)
    > 
    
    （このBabelプラグインを使用すると、dotenvを利用して複数の環境向けに環境変数をJavaScript環境に注入することができます。React Nativeでの使用に最適であり、Webを含むすべての種類の環境で動作します。）
    メリット:
    
    - シンプルでセットアップが容易
    - 既存の .env ファイルをそのまま利用できる
    - 環境変数を直接JavaScriptコードで扱える
    - Webと共通の仕組みを利用可能
    
    デメリット:
    
    - 全ての変数がクライアント側にバンドルされるため、デコンパイルでキーが露出するリスクがある
    - ネイティブコードにアクセスする用途には不向き
    - ビルド時に環境変数がコードに埋め込まれるため、動的変更ができない

# モバイルアプリで使うならどちらか

結論、`react-native-config`になります。理由は以下の通り。

1. セキュリティ面:
    
    react-native-dotenv は全ての環境変数がクライアントにバンドルされるため、リバースエンジニアリングで露出するリスクが高い。
    一方、react-native-config はネイティブコードと統合しやすく、環境変数を秘匿する設計が可能。
    
2. ネイティブコード統合:
react-native-configは info.plist や build.gradle に環境変数を直接渡すことができ、ネイティブ環境での設定が簡単。
3. ビルド環境ごとの柔軟性:
ビルドターゲットに応じて異なる .env ファイルを使用可能で、本番環境と開発環境を分けるのが容易。

とはいえ、クライアントアプリに組み込まれる点は変わらず、公式ドキュメントでもアプリコード内に機密なAPIキーを保存しないことが推奨されています。

> Never store sensitive API keys in your app code. （・・・） Tools like [react-native-dotenv](https://github.com/goatandsheep/react-native-dotenv) and [react-native-config](https://github.com/luggit/react-native-config/) are great for adding environment-specific variables like API endpoints, but they should not be confused with server-side environment variables, which can often contain secrets and API keys.　- （https://reactnative.dev/docs/security#storing-sensitive-info）
> 

よって環境変数に対するベストプラクティスはサーバー管理に落ち着きます。

- 機密な API キーやシークレットは、サーバーサイドで管理し、クライアントアプリから直接アクセスさせないようする
- アプリからのリクエストは、サーバーサイドで認証・検証を行い、必要なデータのみを返すように設計する

# まとめ

これまでの内容から、以下が開発方針としてベストな流れかと思います。

- 開発初期はAPIキーを.envファイルにローカル保存し、.gitignoreによってGit追跡対象外にすることでリモートリポジトリに公開されることを防ぎつつ、react-native-cofigやreact-native-dotenvで環境変数を簡単に管理
- React Nativeを用いたアプリ開発をメインに、Webをサブターゲットに見据える場合は、ネイティブ連携のしやすいreact-native-configを採用
- 将来アプリリリースをする時は、react-native-configやreact-native-dotenvを使用せず、APIキーが格納されるファイル（.envファイルなど）はサーバー保存し、アプリビルドに組み込まれることを防ぐ

あくまでも、react-native-dotenv と react-native-config は機密情報のセキュリティ管理を目的としたものではなく、設定値管理に特化しているということですね。