JAMstackサイトへの動的および非同期機能の追加

公開: 2022-03-10
簡単なまとめ↬サーバーをスキップし、JAMstackを使用してWebサイトやアプリを構築および配信すると、CDNで静的アセットのみを配信できるようになるため、時間、費用、および頭痛の種を節約できます。 ただし、従来のサーバーベースの展開を廃止することのトレードオフは、サイトやアプリでの動的な非同期の相互作用に対する標準的なアプローチが利用できなくなったことを意味します。

これは、JAMstackサイトが動的な相互作用を処理できないことを意味しますか? 絶対にありません!

JAMstackサイトは、非常に動的な非同期の相互作用を作成するのに最適です。 コードの考え方を少し調整するだけで、静的アセットのみを使用して、楽しく没入型のインタラクションを作成できます。

JAMstackを使用して構築されたWebサイト、つまり、JavaScript、マークアップ、およびAPIから構築された静的HTMLファイルとして提供できるWebサイトを見ることがますます一般的になっています。 JAMstackは、インフラストラクチャコストを削減し、配信を高速化し、静的資産を出荷することでサーバーのスケーリングやデータベースの高可用性を維持する必要がなくなるため、パフォーマンスとセキュリティの向上の障壁が低くなるため、企業はJAMstackを気に入っています(つまり、ハッキングされる)。 JAMstackが好きな開発者は、インターネット上でWebサイトを公開する複雑さを軽減します。管理または展開するサーバーがありません。 フロントエンドコードを書くことができ、それは魔法のようにライブになります。

(この場合の「Magic」は自動化された静的展開であり、私が働いているNetlifyを含む多くの企業から無料で利用できます。)

しかし、JAMstackについて開発者と話すことに多くの時間を費やすと、JAMstackが深刻なWebアプリケーションを処理できるかどうかという疑問が生じます。 結局のところ、JAMstackサイトは静的サイトですよね? そして、静的サイトは、できることにおいて非常に制限されていませんか?

これは非常に一般的な誤解です。この記事では、誤解がどこから来ているのかを掘り下げ、JAMstackの機能を確認し、JAMstackを使用して深刻なWebアプリケーションを構築するいくつかの例を紹介します。

JAMstackの基礎

Phil Hawksworthが、JAMStackの実際の意味と、プロジェクトでJAMStackを使用することが理にかなっている場合、およびJAMStackがツールとフロントエンドアーキテクチャにどのように影響するかについて説明します。 関連記事を読む→

ジャンプした後もっと! 以下を読み続けてください↓

JAMstackサイトを「静的」にするものは何ですか?

今日のWebブラウザーは、90年代と同じように、HTML、CSS、およびJavaScriptファイルをロードします。

JAMstackサイトは、その中核として、HTML、CSS、およびJavaScriptファイルでいっぱいのフォルダーです。

これらは「静的アセット」です。つまり、これらを生成するための中間ステップは必要ありません(たとえば、WordPressのようなPHPプロジェクトでは、リクエストごとにHTMLを生成するサーバーが必要です)。

これがJAMstackの真の力です。機能するために特別なインフラストラクチャは必要ありません。 JAMstackサイトは、好みのコンテンツ配信ネットワーク(CDN)に配置し、GitHub Pagesなどのサービスでホストすることで、ローカルコンピューターで実行できます。フォルダーをお気に入りのFTPクライアントにドラッグアンドドロップして、アップロードすることもできます。共有ホスティングに。

静的アセットは必ずしも静的エクスペリエンスを意味するわけではありません

JAMstackサイトは静的ファイルで構成されているため、これらのサイトでのエクスペリエンスは静的であると簡単に推測できます。 しかし、そうではありません!

JavaScriptは、非常に多くの動的な処理を実行できます。 結局のところ、最新のJavaScriptフレームワークは、ビルドステップを完了した後は静的ファイルになります。そして、それらを利用した非常に動的なWebサイトエクスペリエンスの例が何百もあります。

「静的」とは柔軟性がない、または固定されていることを意味するという一般的な誤解があります。 ただし、「静的」とは、「静的サイト」のコンテキストで実際に意味するのは、ブラウザがコンテンツの配信を支援する必要がないことです。サーバーが最初に処理ステップを処理しなくても、ブラウザをネイティブに使用できます。

または、別の言い方をすると:

「静的アセット」は静的アプリを意味するものではありません。 サーバーが不要であることを意味します。

「「

JAMstackはそれを行うことができますか?

誰かが新しいアプリの構築について質問した場合、Gatsby、Eleventy、Nuxt、およびその他の同様のツールなどのJAMstackアプローチの提案を見るのが一般的です。 「静的サイトジェネレーターは_______を実行できません」という反対意見が発生するのも同様に一般的です。ここで、_______は動的なものです。

ただし、前のセクションで触れたように、JAMstackサイトは動的なコンテンツとインタラクションを処理できます。

これは、JAMstackが確実に処理できないと人々が主張するのを繰り返し聞いた、不完全なリストです。

  • データを非同期でロードする
  • 画像の操作などの処理ファイルを処理する
  • データベースからの読み取りとデータベースへの書き込み
  • ユーザー認証を処理し、ログインの背後にあるコンテンツを保護します

次のセクションでは、これらの各ワークフローをJAMstackサイトに実装する方法を見ていきます。

動的なJAMstackの動作を見るのが待ちきれない場合は、最初にデモをチェックしてから、戻ってそれらがどのように機能するかを学ぶことができます。

デモについてのメモ

これらのデモは、フレームワークなしで作成されています。 これらは、HTML、CSS、および標準のJavaScriptのみです。 これらは最新のブラウザ(Chrome、Firefox、Safari、Edgeなど)を念頭に置いて構築されており、JavaScriptモジュール、HTMLテンプレート、FetchAPIなどの新しい機能を利用しています。 ポリフィルは追加されていないため、サポートされていないブラウザを使用している場合、デモはおそらく失敗します。

サードパーティのAPIから非同期でデータを読み込む

「静的ファイルの作成後に新しいデータを取得する必要がある場合はどうなりますか?」

JAMstackでは、組み込みのFetch APIを含む多数の非同期リクエストライブラリを利用して、いつでもJavaScriptを使用してデータを読み込むことができます。

デモ:JAMstackサイトからサードパーティのAPIを検索する

非同期ロードを必要とする一般的なシナリオは、必要なコンテンツがユーザー入力に依存する場合です。 たとえば、 Rick&Morty APIの検索ページを作成する場合、誰かが検索語を入力するまで、どのコンテンツを表示するかわかりません。

これを処理するには、次のことを行う必要があります。

  1. 人々が検索語を入力できるフォームを作成し、
  2. フォームの送信を聞いて、
  3. フォーム送信から検索語を取得し、
  4. 検索語を使用して、非同期リクエストをRick&MortyAPIに送信します。
  5. ページにリクエスト結果を表示します。

まず、検索結果を含むフォームと空の要素を作成する必要があります。これは次のようになります。

 <form> <label for="name">Find characters by name</label> <input type="text" name="name" required /> <button type="submit">Search</button> </form> <ul></ul>

次に、フォームの送信を処理する関数を作成する必要があります。 この関数は次のようになります。

  • デフォルトのフォーム送信動作を防止する
  • フォーム入力から検索語を取得する
  • Fetch APIを使用して、検索語を使用してRick&MortyAPIにリクエストを送信します
  • ページに検索結果を表示するヘルパー関数を呼び出す

また、ハンドラー関数を呼び出す送信イベントのフォームにイベントリスナーを追加する必要があります。

そのコード全体は次のようになります。

 <script type="module"> import showResults from './show-results.js'; const form = document.querySelector('form'); const handleSubmit = async event => { event.preventDefault(); // get the search term from the form input const name = form.elements['name'].value; // send a request to the Rick & Morty API based on the user input const characters = await fetch( `https://rickandmortyapi.com/api/character/?name=${name}`, ) .then(response => response.json()) .catch(error => console.error(error)); // add the search results to the DOM showResults(characters.results); }; form.addEventListener('submit', handleSubmit); </script>

注:動的なJAMstackの動作に焦点を合わせ続けるために、showResultsなどのユーティリティ関数がどのように記述されるかについては説明しません。 ただし、コードは完全にコメント化されているので、ソースをチェックして、どのように機能するかを確認してください。

このコードを配置すると、ブラウザにサイトを読み込むことができ、結果が表示されない空のフォームが表示されます。

空の検索フォーム
空の検索フォーム(大プレビュー)

文字名(「rick」など)を入力して「search」をクリックすると、名前に「rick」が含まれている文字のリストが表示されます。

下に表示されている「リック」という名前の文字で「リック」で埋められた検索フォーム。
フォームに記入すると検索結果が表示されます。 (大プレビュー)

おい! その静的サイトはデータを動的にロードするだけでしたか? 聖なるバケツ!

ライブデモでこれを試してみるか、詳細については完全なソースコードを確認してください。

ユーザーのデバイスから離れた高価なコンピューティングタスクを処理する

多くのアプリでは、画像の処理など、かなりリソースを消費する処理を実行する必要があります。 これらの種類の操作の一部はクライアント側のJavaScriptのみを使用して可能ですが、ユーザーのデバイスにすべての機能を実行させることは必ずしも優れたアイデアではありません。 低電力のデバイスを使用している場合、またはバッテリー寿命の最後の5%を延長しようとしている場合、デバイスに大量の作業を行わせることは、おそらく彼らにとって苛立たしい経験になるでしょう。

つまり、JAMstackアプリは運が悪いということですか? 全くない!

JAMstackの「A」はAPIを表します。 これは、その作業をAPIに送信し、ユーザーのコンピューターファンを「ホバー」設定まで回転させないようにすることができることを意味します。

「でも待って」と言うかもしれません。 「アプリでカスタム作業を行う必要があり、その作業にAPIが必要な場合、それは単にサーバーを構築しているという意味ではありませんか?」

サーバーレス機能の力のおかげで、そうする必要はありません!

サーバーレス関数(「ラムダ関数」とも呼ばれます)は、サーバーの定型文を必要としない一種のAPIです。 昔ながらのJavaScript関数を作成することができ、デプロイ、スケーリング、ルーティングなどのすべての作業は、選択したサーバーレスプロバイダーにオフロードされます。

サーバーレス機能を使用することは、サーバーがないことを意味するわけではありません。 サーバーについて考える必要がないということです。

「「

サーバーレス機能は、JAMstackのピーナッツバターです。サーバーコードやDevOpsの処理を要求することなく、強力で動的な機能の全世界を解き放ちます。

デモ:画像をグレースケールに変換する

次のことを行う必要のあるアプリがあるとしましょう。

  • URLから画像をダウンロードする
  • その画像をグレースケールに変換します
  • 変換された画像をGitHubリポジトリにアップロードします

私の知る限り、このような画像変換を完全にブラウザで行う方法はありません。たとえあったとしても、かなりリソースを消費するため、ユーザーにそのような負荷をかけたくないでしょう。 'デバイス。

代わりに、サーバーレス関数に変換するURLを送信できます。これにより、手間のかかる作業が行われ、変換された画像にURLが返されます。

サーバーレス関数には、Netlify関数を使用します。 このサイトのコードでは、ルートレベルに「functions」というフォルダーを追加し、その中に「convert-image.js」という新しいファイルを作成します。 次に、ハンドラーと呼ばれるものを記述します。これは、ご想像のとおり、サーバーレス関数へのリクエストを受信して​​処理します。

画像を変換するには、次のようになります。

 exports.handler = async event => { // only try to handle POST requests if (event.httpMethod !== 'POST') { return { statusCode: 404, body: '404 Not Found' }; } try { // get the image URL from the POST submission const { imageURL } = JSON.parse(event.body); // use a temporary directory to avoid intermediate file cruft // see https://www.npmjs.com/package/tmp const tmpDir = tmp.dirSync(); const convertedPath = await convertToGrayscale(imageURL, tmpDir); // upload the processed image to GitHub const response = await uploadToGitHub(convertedPath, tmpDir.name); return { statusCode: 200, body: JSON.stringify({ url: response.data.content.download_url, }), }; } catch (error) { return { statusCode: 500, body: JSON.stringify(error.message), }; } };

この関数は次のことを行います。

  1. リクエストがHTTPPOSTメソッドを使用して送信されたことを確認します
  2. POST本文から画像のURLを取得します
  3. 関数の実行が完了するとクリーンアップされるファイルを保存するための一時ディレクトリを作成します
  4. 画像をグレースケールに変換するヘルパー関数を呼び出します
  5. 変換された画像をGitHubにアップロードするヘルパー関数を呼び出します
  6. HTTP200ステータスコードと新しくアップロードされた画像のURLを含む応答オブジェクトを返します

画像変換やGitHubへのアップロードでヘルパーがどのように機能するかについては説明しませんが、ソースコードには十分なコメントが付けられているため、どのように機能するかを確認できます。

次に、処理用のURLを送信するために使用するフォームと、前後を表示する場所を追加する必要があります。

 <form action="/.netlify/functions/convert-image" method="POST" > <label for="imageURL">URL of an image to convert</label> <input type="url" name="imageURL" required /> <button type="submit">Convert</button> </form> <div></div>

最後に、フォームにイベントリスナーを追加して、URLをサーバーレス関数に送信して処理できるようにする必要があります。

 <script type="module"> import showResults from './show-results.js'; const form = document.querySelector('form'); form.addEventListener('submit', event => { event.preventDefault(); // get the image URL from the form const imageURL = form.elements['imageURL'].value; // send the image off for processing const promise = fetch('/.netlify/functions/convert-image', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ imageURL }), }) .then(result => result.json()) .catch(error => console.error(error)); // do the work to show the result on the page showResults(imageURL, promise); }); </script>

サイトを(新しい「関数」フォルダーとともに)Netlifyにデプロイした後、および/またはCLIでNetlify Devを起動した後、ブラウザーにフォームが表示されます。

空の画像変換フォーム
画像のURLを受け入れる空のフォーム(大きなプレビュー)

フォームに画像のURLを追加して[変換]をクリックすると、変換が行われている間、しばらくの間「処理中…」が表示され、次に元の画像とそれに新しく作成されたグレースケールの対応物が表示されます。

画像のURLが入力されたフォーム。左側に元の画像、右側に変換された画像が表示されます
画像はフルカラーからグレースケールに変換されます。 (大プレビュー)

ああダン! 私たちのJAMstackサイトは、かなり深刻なビジネスを処理したばかりで、サーバーについて一度考えたり、ユーザーのバッテリーを消耗したりする必要はありませんでした。

データベースを使用してエントリを保存および取得する

多くのアプリでは、必然的にユーザー入力を保存する機能が必要になります。 つまり、データベースが必要です。

あなたはこう考えているかもしれません。 ジグは上がっていますか? 確かに、JAMstackサイト(フォルダ内のファイルのコレクションにすぎないとおっしゃっています)は、データベースに接続できません。」

Aucontraire。

前のセクションで見たように、サーバーレス関数を使用すると、独自のサーバーを作成しなくても、あらゆる種類の強力な処理を実行できます。

同様に、サービスとしてのデータベース(DBaaS)ツール(Faunaなど)を使用して、データベースを自分でセットアップしたりホストしたりしなくても、データベースの読み取りと書き込みを行うことができます。

DBaaSツールは、Webサイト用のデータベースを設定するプロセスを大幅に簡素化します。新しいデータベースの作成は、保存するデータの種類を定義するのと同じくらい簡単です。 ツールは、作成、読み取り、更新、削除(CRUD)操作を管理するためのすべてのコードを自動的に生成し、APIを介して使用できるようにするため、実際にデータベースを管理する必要はありません。 私たちはそれを使うようになります。

デモ:請願ページを作成する

請願書のデジタル署名を収集する小さなアプリを作成する場合は、それらの署名を保存するデータベースを設定し、ページがそれらを読み取って表示できるようにする必要があります。

このデモでは、DBaaSプロバイダーとしてFaunaを使用します。 動物相のしくみについては詳しく説明しませんが、データベースのセットアップに必要なわずかな労力を示すために、各ステップをリストし、クリックしてすぐに使用できるデータベースを取得しましょう。

  1. https://fauna.comで動物相アカウントを作成します
  2. 「新しいデータベースを作成する」をクリックします
  3. データベースに名前を付けます(例:「dynamic-jamstack-demos」)
  4. 「作成」をクリックします
  5. 次のページの左側のメニューで「セキュリティ」をクリックします
  6. 「新しいキー」をクリックします
  7. 役割のドロップダウンを「サーバー」に変更します
  8. キーの名前を追加します(例:「DynamicJAMstackDemos」)
  9. アプリで使用できるように安全な場所にキーを保存します
  10. 「保存」をクリックします
  11. 左側のメニューで「GraphQL」をクリックします
  12. 「スキーマのインポート」をクリックします
  13. 次のコードを含むdb-schema.gqlというファイルをアップロードします。
 type Signature { name: String! } type Query { signatures: [Signature!]! }

スキーマをアップロードすると、データベースを使用できるようになります。 (真剣に。)

13のステップはたくさんありますが、これらの13のステップで、データベース、GraphQL API、容量の自動管理、スケーリング、デプロイメント、セキュリティなどがすべてデータベースの専門家によって処理されました。 無料で。 生きるなんて時間だ!

試してみるために、左側のメニューの「GraphQL」オプションは、CRUD操作を実行できるようにする利用可能なクエリとミューテーションに関するドキュメントを備えたGraphQLエクスプローラーを提供します。

この投稿ではGraphQLクエリとミューテーションの詳細については説明しませんが、その仕組みの入門書が必要な場合は、EvePorcelloがGraphQLクエリとミューテーションの送信に関する優れたイントロを作成しました。

データベースの準備ができたら、データベースに新しい署名を格納するサーバーレス関数を作成できます。

 const qs = require('querystring'); const graphql = require('./util/graphql'); exports.handler = async event => { try { // get the signature from the POST data const { signature } = qs.parse(event.body); const ADD_SIGNATURE = ` mutation($signature: String!) { createSignature(data: { name: $signature }) { _id } } `; // store the signature in the database await graphql(ADD_SIGNATURE, { signature }); // send people back to the petition page return { statusCode: 302, headers: { Location: '/03-store-data/', }, // body is unused in 3xx codes, but required in all function responses body: 'redirecting...', }; } catch (error) { return { statusCode: 500, body: JSON.stringify(error.message), }; } };

この関数は次のことを行います。

  1. フォームPOSTデータから署名値を取得します
  2. 署名をデータベースに格納するヘルパー関数を呼び出します
  3. データベースに書き込むためのGraphQLミューテーションを定義します
  4. GraphQLヘルパー関数を使用してミューテーションを送信します
  5. データを送信したページにリダイレクトします

次に、データベースからすべての署名を読み取るサーバーレス関数が必要です。これにより、請願を支持する人の数を示すことができます。

 const graphql = require('./util/graphql'); exports.handler = async () => { const { signatures } = await graphql(` query { signatures { data { name } } } `); return { statusCode: 200, body: JSON.stringify(signatures.data), }; };

この関数はクエリを送信して返します。

機密キーとJAMstackアプリに関する重要な注意事項

このアプリについて注意すべきことの1つは、サーバーレス関数を使用してこれらの呼び出しを行うことです。これは、このデータベースへの読み取りおよび書き込みアクセス権があることを証明するプライベートサーバーキーをFaunaに渡す必要があるためです。 このキーをクライアント側のコードに入れることはできません。これは、誰もがこのキーをソースコードで見つけて、データベースに対してCRUD操作を実行するために使用できることを意味するためです。 サーバーレス機能は、JAMstackアプリで秘密鍵を秘密に保つために重要です。

サーバーレス関数を設定したら、署名を追加するための関数に送信するフォーム、既存の署名を表示する要素、および関数を呼び出して署名を取得して表示するためのJSを少し追加できます。エレメント:

 <form action="/.netlify/functions/add-signature" method="POST"> <label for="signature">Your name</label> <input type="text" name="signature" required /> <button type="submit">Sign</button> </form> <ul class="signatures"></ul> <script> fetch('/.netlify/functions/get-signatures') .then(res => res.json()) .then(names => { const signatures = document.querySelector('.signatures'); names.forEach(({ name }) => { const li = document.createElement('li'); li.innerText = name; signatures.appendChild(li); }); }); </script>

これをブラウザにロードすると、その下に署名が付いた請願書が表示されます。

以下の署名のリストを含む空の請願書
デジタル署名を受け入れる空のフォーム(大プレビュー)

次に、署名を追加すると…

フィールドに名前が記載されているが、まだ提出されていない請願書
名前が記入された請願書(大プレビュー)

…送信すると、リストの下部に名前が追加されます。

リストの下部に新しい署名が付いた空の請願書
請願書がクリアされ、新しい署名がリストの一番下に追加されます。 (大プレビュー)

ホットディジティドッグ! 約75行のコードと7行のデータベーススキーマを備えた、データベースを利用した完全なJAMstackアプリを作成しました。

ユーザー認証でコンテンツを保護する

「さて、あなたは確かに今回は立ち往生しています」とあなたは考えているかもしれません。 「JAMstackサイトがユーザー認証を処理する方法はありません。 それは一体どうやって機能するのでしょうか?!」

私の友人、それがどのように機能するかをお話しします:私たちの信頼できるサーバーレス機能とOAuthを使って。

OAuthは、パスワードを共有するのではなく、アプリにアカウント情報への制限付きアクセスを許可するために広く採用されている標準です。 別のサービスを使用してサービスにログインしたことがある場合(たとえば、「Googleアカウントでサインイン」)、以前にOAuthを使用したことがあります。

注: OAuthの仕組みについては詳しく説明しませんが、Aaron Pareckiは、詳細とワークフローをカバーするOAuthの概要をしっかりと書いています。

JAMstackアプリでは、OAuthと、ユーザーを識別し、コンテンツを保護し、ログインしたユーザーのみがコンテンツを表示できるようにするために提供されるJSON Web Token(JWT)を利用できます。

デモ:保護されたコンテンツを表示するにはログインが必要

ログインしたユーザーにのみコンテンツを表示するサイトを構築する必要がある場合は、いくつかのことが必要です。

  1. ユーザーとサインインフローを管理するIDプロバイダー
  2. ログインとログアウトを管理するためのUI要素
  3. JWTを使用してログインしたユーザーをチェックし、保護されたコンテンツが提供されている場合はそれを返すサーバーレス関数

この例では、Netlify Identityを使用します。これにより、認証を追加するための非常に快適な開発者エクスペリエンスが提供され、ログインおよびログアウトアクションを管理するためのドロップインウィジェットが提供されます。

有効にするには:

  • Netlifyダッシュボードにアクセスします
  • サイトリストから認証が必要なサイトを選択してください
  • 上部のナビゲーションで「ID」をクリックします
  • 「IDを有効にする」ボタンをクリックします

ログアウトしたコンテンツを表示するマークアップを追加し、ログイン後に保護されたコンテンツを表示する要素を追加することで、NetlifyIdentityをサイトに追加できます。

 <div class="content logged-out"> <h1>Super Secret Stuff!</h1> <p> only my bestest friends can see this content</p> <button class="login">log in / sign up to be my best friend</button> </div> <div class="content logged-in"> <div class="secret-stuff"></div> <button class="logout">log out</button> </div>

このマークアップは、CSSに依存して、ユーザーがログインしているかどうかに基づいてコンテンツを表示します。 ただし、実際にコンテンツを保護するためにこれに依存することはできません。誰でもソースコードを表示して、秘密を盗むことができます。

代わりに、保護されたコンテンツを含む空のdivを作成しましたが、実際にそのコンテンツを取得するには、サーバーレス関数にリクエストを送信する必要があります。 これがどのように機能するかについては、後ほど詳しく説明します。

次に、ログインボタンを機能させるためのコードを追加し、保護されたコンテンツを読み込んで、画面に表示する必要があります。

 <script src="https://identity.netlify.com/v1/netlify-identity-widget.js"></script> <script> const login = document.querySelector('.login'); login.addEventListener('click', () => { netlifyIdentity.open(); }); const logout = document.querySelector('.logout'); logout.addEventListener('click', () => { netlifyIdentity.logout(); }); netlifyIdentity.on('logout', () => { document.querySelector('body').classList.remove('authenticated'); }); netlifyIdentity.on('login', async () => { document.querySelector('body').classList.add('authenticated'); const token = await netlifyIdentity.currentUser().jwt(); const response = await fetch('/.netlify/functions/get-secret-content', { headers: { Authorization: `Bearer ${token}`, }, }).then(res => res.text()); document.querySelector('.secret-stuff').innerHTML = response; }); </script>

このコードの機能は次のとおりです。

  1. ログインモーダルを作成し、Netlify Identityを使用してOAuthワークフローを処理し、ログインしたユーザーの情報へのアクセスをアプリに提供するヘルパーライブラリであるNetlifyIdentityウィジェットをロードします
  2. NetlifyIdentityログインモーダルを開くようにトリガーするイベントリスナーをログインボタンに追加します
  3. NetlifyIdentityログアウトメソッドを呼び出すログアウトボタンにイベントリスナーを追加します
  4. ログアウトするためのイベントハンドラーを追加して、ログアウト時に認証されたクラスを削除します。これにより、ログインしたコンテンツが非表示になり、ログアウトしたコンテンツが表示されます。
  5. ログイン用のイベントハンドラーを追加します。
    1. 認証されたクラスを追加して、ログインしたコンテンツを表示し、ログアウトしたコンテンツを非表示にします
    2. ログインしたユーザーのJWTを取得します
    3. サーバーレス関数を呼び出して保護されたコンテンツを読み込み、AuthorizationヘッダーでJWTを送信します
    4. ログインしたユーザーが表示できるように、シークレットコンテンツをsecret-stuffdivに配置します

現在、そのコードで呼び出しているサーバーレス関数は存在しません。 次のコードで作成しましょう。

 exports.handler = async (_event, context) => { try { const { user } = context.clientContext; if (!user) throw new Error('Not Authorized'); return { statusCode: 200, headers: { 'Content-Type': 'text/html', }, body: `

招待されました、$ {user.user_metadata.full_name}!

あなたがこれを読むことができれば、それは私たちが親友であることを意味します。

これが私の誕生日パーティーの秘密の詳細です:
jason.af/party

`、 }; } catch(エラー){ 戻る { statusCode:401、 本文:「許可されていません」、 }; } };

この関数は次のことを行います。

  1. サーバーレス関数のコンテキスト引数でユーザーをチェックします
  2. ユーザーが見つからない場合はエラーをスローします
  3. ログインしたユーザーがシークレットコンテンツを要求したことを確認した後、シークレットコンテンツを返します

Netlify関数は、AuthorizationヘッダーでNetlify Identity JWTを検出し、その情報を自動的にコンテキストに入れます。つまり、JWTを検証するためのコードを記述しなくても、有効なJWTをチェックできます。

このページをブラウザにロードすると、最初にログアウトしたページが表示されます。

ログインまたはアカウントの作成に関する情報を示すログアウトビュー
ログアウトすると、ログインに関する情報しか表示されません。(大きなプレビュー)

ボタンをクリックしてログインすると、NetlifyIdentityウィジェットが表示されます。

ログインフォームが表示されたサインアップタブとログインタブを表示するモーダルウィンドウ
Netlify Identity Widgetは、ログイン/サインアップエクスペリエンス全体を提供します。 (大プレビュー)

ログイン(またはサインアップ)すると、保護されたコンテンツが表示されます。

誕生日パーティーに関する情報を表示するログインビュー
ログインすると、保護されたコンテンツが表示されます。 (大プレビュー)

うわー! JAMstackアプリにユーザーログインと保護されたコンテンツを追加しました。

次はどうする

JAMstackは、「単なる静的サイト」ではありません。ユーザーの操作に応答したり、データを保存したり、ユーザー認証を処理したり、最新のWebサイトでやりたいことは何でもできます。 そして、サーバーをプロビジョニング、構成、または展開する必要はありません。

JAMstackで何を構築したいですか? JAMstackが処理できるとまだ確信していないものはありますか? 私はそれについて聞きたいです— Twitterまたはコメントで私を襲ってください!