[basecamp/lexxy] 認証付きActiveStorageアップロードのサポート追加

basecamp/lexxy

Context

ActiveStorageを使用したファイルアップロードにおいて、認証が必要なストレージコントローラーを使用する場合、通常のXHRリクエストではCookieが送信されないため、認証に失敗する問題がありました。特にCORS環境下では、withCredentialsオプションを明示的に有効化する必要があります。

このPRは、Lexxyエディタで認証付きアップロードをサポートするための設定オプションと、テスト環境での検証機構を追加します。

Technical Detail

グローバル設定の追加

新たにauthenticatedUploads設定が追加され、ActiveStorageのアップロードリクエストにwithCredentials: trueを設定できるようになりました。

const global = new Configuration({
  attachmentTagName: "action-text-attachment",
  authenticatedUploads: false  // 新規追加
})

この設定を有効化するには、以下のように記述します。

import * as Lexxy from "lexxy"
Lexxy.configure({ global: { authenticatedUploads: true }})

DirectUploadでの認証対応

ActionTextAttachmentUploadNodeにおいて、DirectUploadの2つのフックポイントでwithCredentialsを設定します。

upload.delegate = {
  directUploadWillCreateBlobWithXHR: (request) => {
    if (shouldAuthenticateUploads) request.withCredentials = true
  },
  directUploadWillStoreFileWithXHR: (request) => {
    if (shouldAuthenticateUploads) request.withCredentials = true
    // ...
  }
}
  • directUploadWillCreateBlobWithXHR: Blobメタデータ作成時のリクエスト
  • directUploadWillStoreFileWithXHR: 実際のファイルアップロード時のリクエスト

両方のフェーズで認証情報を送信する必要があります。

CORS設定とサブドメイン対応

テスト用のダミーアプリケーションでは、rack-cors gemを使用してCORS設定を行います。

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins /^http:\/\/(([^.]*\.)?lexxy\.)?localhost(:\d+)?$/i

    resource "/authenticated_direct_uploads", methods: :post, headers: :any, credentials: true
    resource "/authenticated_direct_uploads/*", methods: [:post, :put], headers: :any, credentials: true
    resource "/rails/active_storage/*", methods: [:post, :put], headers: :any, credentials: true
  end
end

認証付きアップロード専用のコントローラーも追加されています。

class AuthenticatedDirectUploadsController < ActiveStorage::DirectUploadsController
  skip_forgery_protection

  before_action :require_auth_cookie

  private
    def require_auth_cookie
      unless cookies[:auth_token].present?
        head :unauthorized
      end
    end
end

このコントローラーはstorage.lexxy.localhostサブドメインでマウントされ、Cookie認証を要求します。

resources "authenticated_direct_uploads",
  only: [:create, :update],
  subdomain: LexxyApp.authenticated_storage_subdomain

Attachment Nodeのリファクタリング

PRには、Attachment関連のコードのクリーンアップも含まれています。

重要な変更点:

  1. conversion関数の引数: Lexicalのスタイルガイドに従い、conversion関数は要素を引数として受け取るように修正されました。
// 変更前
[this.TAG_NAME]: (attachment) => {
  return {
    conversion: () => ({
      node: new ActionTextAttachmentNode({ ... })
    })
  }
}

// 変更後
[this.TAG_NAME]: () => {
  return {
    conversion: (attachment) => ({
      node: new ActionTextAttachmentNode({ ... })
    })
  }
}
  1. グローバル設定の評価タイミング: タグ名などのグローバル設定は、静的クラスレベルのgetterで評価されるようになりました。
static get TAG_NAME() {
  return Lexxy.global.get("attachmentTagName")
}

static importDOM() {
  return {
    [this.TAG_NAME]: (element) => { ... }
  }
}

テストの追加

認証付きアップロードの動作を検証するシステムテストが追加されています。

test "authenticated upload succeeds with auth cookie" do
  add_auth_cookie
  visit edit_post_path(posts(:empty),
    authenticated_storage: true,
    configure_authenticated_uploads: true)

  attach_file file_fixture("example.png") do
    click_on "Upload file"
  end

  assert_image_figure_attachment content_type: "image/png", caption: "example.png"
end

Capybaraの設定も、サブドメインテストに対応するよう更新されています。

Capybara.app_host = "http://lexxy.localhost"

利用上の注意

認証付きアップロードを使用する際は、以下の設定が必要です。

  1. Cookie domain: サブドメイン間でCookieを共有できるよう、適切なドメイン設定を行う
  2. CORS設定: credentials: trueを含むCORS設定を行う
  3. CSRF対策: 認証コントローラーでは適切なCSRF設定を行う

これらの設定が正しく行われていない場合、アップロードは401 Unauthorizedで失敗します。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成(Title, Context, Technical Detail)、カスタムMarkdown構文、対象読者への適合性のすべてにおいてガイドラインを遵守しています。特に、ファイル名付きコードブロックやPRリンクが正しく使用されており、技術記事としての体裁が整っています。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

記事で引用されているコードは、PRのDiffと完全に一致しており、正確です。`withCredentials`やCORS、ActiveStorageのフックに関する説明も技術的に正しく、変更内容の理解を深めるものになっています。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

PRのタイトルは「Attachment configs」と抽象的ですが、記事は「認証付きActiveStorageアップロードのサポート追加」という主要な変更点に焦点を当てており、内容を的確に要約しています。PRのDescriptionやDiffに存在する事実のみに基づいて記述されており、ハルシネーションは見られません。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除