辛宝Otto

辛宝Otto 的玄酒清谈

北漂前端程序员儿 / 探索新事物 / Web Worker 主播之一/内向话痨
xiaoyuzhou
email

技術の試行錯誤 xLog 2 xlogの認証を深く理解する

技術の試行 xLog 2 xlog の認証を深く理解する

内部リンク

  • [[技術の試行 xLog 1 実現可能性の探求]]
  • [[技術の試行 xLog 2 xlog の認証を深く理解する]]
  • [[技術の試行 xLog 3 obsidian プラグインの実装]]
  • [[技術の試行 xLog 4 unStorage を使って xLogDriver をラップ]]
  • [[速通 - xLog の背後にある CrossBell SDK]]
  • [[公式 XLOG Obsidian プラグインから学べること]]
  • [[Obsidian Sync To Xlog プラグインの開発 - obsidian の画像処理]]
  • [[速通 - CrossBell のオープンソース作品]]
  • [[速通 Obsidian Docs - プラグイン開発に重点を置く]]

この記事は [[技術の試行 xLog 1 実現可能性の探求]] の内容を引き継いでいます。

この記事では、xlog 記事の管理を実現し、自分のコンテンツの作成、削除、更新、取得を公式の openapi に基づいて行います。この記事の価値は 5 コインの感謝です、えへへ。

背景#

xlog 記事の管理操作を実現するには認証が必要です。どうやってあなたがあなたであることを証明し、他の人の記事を変更できるのでしょうか? web2 の分野では、一般的にアカウントとパスワードを使用して jwt を生成し、ユーザーを模倣したり、oauth を通じて特定の権限範囲の access-token を取得したりします。

私たちの技術的前提は、任意の実行環境をサポートし、ブラウザや node.js などの異なる実行環境を同時にサポートすることですので、ウェブ端末の小狐 metamask による認証は考慮しません。

技術実装#

いくつかの探索を経て、公式メンバーの diygod の指導を受けて、現在少なくともデータ認証管理を実現する方法が二つあります。秘密鍵と認証コードで、後者を推奨します。

プライベートキーによる認証#

まずはプライベートキー、ウォレットの秘密鍵を使用します。これは万能の私が私であることを証明する方法で、公式 sdk もプライベートキーを使用して認証を実現することをサポートしています。

例えば、ここに https://crossbell.js.org/#md:connect-with-private-key

プライベートキーはどこから来るのでしょうか?小狐の例を挙げます:

image.png

アカウントの詳細には、Show Private Key という項目があります。公式 SDK と組み合わせることで認証を実現できます。

必ず注意してください:プライベートキーは非常に機密性が高く、使用することは非常に危険です。ここでは技術的な紹介のみです。

ユーザーと開発者には、以下の認証トークンの方法をお勧めします。

siwe 認証による認証#

SIWE は sign in with ethereum の略です。

siwe 認証には以下のステップがあります:

  • siwe 機能を有効にする
  • トークンを取得する
  • api を通じて認証を得る

siwe 機能を有効にする#

まず、自分の xlog コンソール https://xlog.app/dashboard/ にアクセスし、左側のメニューの最後の列で設定を選択します。

xSettings を選択すると、以下のように表示されます:

image.png

私は web3 にあまり詳しくないので、口語的に表現します。丸い枠内の説明はこう理解できます。主に Sync Operator 部分です:

  • 操作の認可。
  • 同期操作。Sync Operator を有効にすることで、他の方法で Crossbell にコンテンツを同期することができます。つまり、xlog です。

一旦有効にすれば、コードを通じて xlog にコンテンツを同期する能力を持つことになります。

トークンを取得する#

現在、トークンを取得する最も簡単な方法は、コンソールで以下の操作を行うことです:

xsetting ページで、右クリックして検査を選択するか、開発者モードを有効にするか、F12 を押します。Chrome の使用をお勧めします。モジュールがポップアップし、コンソールを選択して、以下のコードをコピーしてコンソールに貼り付け、Enter を押すと、一連の文字が返されます。

JSON.parse(localStorage.getItem('connect-kit:account')).state.wallet.siwe.token

このコードの目的は、siwe のトークン情報を取得することです。他にも取得方法があるはずですが、現在の方法が最も簡単です。

このコードを入力して返される内容が必要なトークン情報ですので、自分で保存してください。

両端のシングルクォートに注意してください。内容だけで大丈夫です。(まあ、私は防止設計をして、プログラムの互換性を持たせますが。)

コンソールから返されたこの長い文字列をコピーしてください。これが認証トークンと呼ばれ、プラグインで使用されます。

開発者にとっては、node.js プロジェクトで .env に保存し、github で secret に保存します。明文での露出を避けるためです。

api 実践#

補足:crossbell の sdk を使用することもお勧めします。効果は同じです。

先ほど取得したトークンを使って、https://indexer.crossbell.io/docs#/Siwe 公式が提供する文書にアクセスします。必要なすべてのものがここにあります。

image.png

ページの最上部に緑色の Authorize ボタンがあります。クリックするとポップアップが表示され、先ほどのトークンを siwe の内容に記入します。

image.png

認可をクリックすると、以降のリクエストのヘッダーに Authorization: Bearer ${token} が追加されます。

例えば、GET /v1/siwe/account を使用すると、現在の私たちが誰であるかを取得できます。

image.png

残りのことは簡単です。以下のいくつかのインターフェースを使って実践できます:

  • PUT /v1/siwe/contract/characters/{characterId}/notes ユーザーに新しい記事を作成する
  • POST /v1/siwe/contract/characters/{characterId}/notes/{noteId}/metadata 指定された noteId の記事を更新する
  • Delete /v1/siwe/contract/characters/{characterId}/notes/{noteId} 指定された記事を削除する

いくつかのコードスニペットを提供します。何度か試した結果、以下のコードスニペットが有効です。

まずは記事を作成する:

const title = '記事のタイトル'
const content = '記事の内容'
const base = "https://indexer.crossbell.io";
const ottoCharId = ''
const token = ''

const createPost = async () => {
  const url = `/v1/siwe/contract/characters/${ottoCharId}/notes`;

  const finalUrl = base + url;

  axios
    .request({
      method: "put",
      url: finalUrl,
      headers: {
        Authorization: `Bearer ${token}`,
      },
      data: {
        metadata: {
          tags: ["post"],
          type: "note",
          title: title,
          content: content,
          summary: "",
        sources: ["xlog"],
          attributes: [
            {
              value: "play-xlog-01", // ここはカスタムスラッグ
              trait_type: "xlog_slug",
            },
          ],
          attachments: [
            {
              name: "cover", // カバー
              address: "",
              mime_type: "",
            },
          ],
        },
        locked: false,
        linkItemType: null,
      },
    })
    .then((res) => {
      console.log(2, res.data);
    })
    .catch((err) => {
      console.log(3, err);
    });
};

次に記事を更新します。ここでの mode は文字通り replace が簡単です。

const updatePost = async () => {
  const noteId = 29;
  const mode = "replace"; //'merge'

  const updatePost =
    base +
    `/v1/siwe/contract/characters/${ottoCharId}/notes/${noteId}/metadata`;

  axios
    .request({
      method: "post",
      url: updatePost,
      headers: {
        Authorization: `Bearer ${token}`,
      },
      data: {
        metadata: {
          tags: ["post", "新しいアイデア"],
          type: "note",
          title: title,
          content: content,
          sources: ["xlog"],
          // summary: "",
          attributes: [
            {
              value: "play-xlog-01",
              trait_type: "xlog_slug",
            },
          ],
          attachments: [
            {
              name: "cover",
              address: "",
              mime_type: "",
            },
          ],
        },
        mode,
      },
    })
    .then((res) => {
      console.log(JSON.stringify(res.data, null, 2));
    })
    .catch((err) => {
      console.log(3, err);
    });
};

最後に記事を削除します。

const deletePost = async () => {
  const characterId = '';
  const noteId = '';

  const deletePost =
    base + `/v1/siwe/contract/characters/${characterId}/notes/${noteId}`;

  axios
    .request({
      method: "delete",
      url: deletePost,
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })
    .then((res) => {
      console.log(2, res.data);
    })
    .catch((err) => {
      console.log(3, err);
    });
};

落とし穴の経験#

記事のボディは、リストページの返却体とは異なり、主に content が一層包まれているかどうか、つまりリクエストパラメータとデータベースに入るデータが異なるため、少し落とし穴があります。最終的に記事作成のパラメータは使用可能です。

公式は入力パラメータに対して比較的寛容で、どんなパラメータでも受け入れます。笑ってしまいますが、誤ったパラメータはリストページの表示を妨げることがあり、長い間排除作業を行い、目が疲れましたが、公式のソースコードに慣れたら、制限を加える必要があります。

展望#

上記の api 実践内容をもとに、今後以下のことが可能になります:

  • node スクリプトを作成し、記事の作成と更新を実現する
  • 例えば、github actions で、markdown をプッシュするたびに関数を呼び出し、xlog に同期する
  • 例えば、obsidian でプラグインを作成し、右クリックで xlog にアップロードする
  • 自分の cms バックエンドを接続し、記事管理を行う

次に、私は自分の obsidian プラグインを改造し、ファイルを xlog にアップロードする機能を実現します。

image.png

ご期待ください。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。