Cloudinary におけるアクセス制限とウォーターマークの除去対策

Cloudinary のアクセス制限には、Private と Authenticated があり、さらにアカウントの Strict Transformations という設定もあります。これらの設定による動きの違いと、アクセス制限を使って画像のウォーターマークを除去されないようにする対策を紹介します。
2020.07.09

Guten Abend!ベルリンから伊藤です。

画像や動画のデジタルメディア管理・変換 SaaS、Cloudinaryを使うと、画像最適化ウォーターマーク画像への変換が簡単に実現できます。

例えばウォーターマークであれば、写真画像のURLに、ロゴ画像と変換パラメータを組み合わせるだけで、ロゴ入り画像が配信できます。

Image with watermark

https://res.cloudinary.com/CLOUD-NAME/image/upload/c_scale,w_300/l_logo,c_scale,g_south_east,w_100,x_10,y_10,o_70/v1/ito-test/Reichstag.jpg

◆ 関連: Cloudinaryの画像変換パラメータまとめ 〜 オーバーレイ・アンダーレイ | Developers.IO

しかし、デフォルトでは Cloudinary ではアセットURLのパラメータを変更するだけで動的に変換させることが可能ですので、パラメータを操作するとウォーターマークも簡単に除去できてしまいます。そんな時に、Cloudinaryでは変換を制限させるためのオプションがあります。

本稿では、アクセス制限の設定による違いと、ウォーターマーク除去の対策をご紹介します。

はじめに

実用例

表示速度が爆速で話題になった、Cloudinary を導入している dev.to では、記事のトップ画像で例えば以下のよう(一部加工済み)にfetchでパブリックURLから画像を取り込んでいますが、s--SIGNATURE-- の部分で署名付きURLが使われており、動的な変換ができないよう制限されていました。 仮に余計な変換パラメータを加えてアクセスすると、404エラーとなります。

https://res.cloudinary.com/practicaldev
 /image/fetch
 /s--nJaC4tAU--
 /c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000
 /https://XXX.s3.amazonaws.com/test.png

◆ 関連: dev.toに学ぶ画像最適化のヒント #Cloudinary | Developers.IO

2つのアクセスコントロール

Cloudinaryへアップロードしたアセットはオリジナル・変換後とも、デフォルトでは誰でもアクセスすることができます。この状態ではパラメータ操作による即座の変換が可能です。アクセスを制限するために、2種類のアクセスコントロールがあります。

  • Private: アセットのオリジナルへのアクセスのみ制限し、アセットの変換画像にはアクセスを許可
  • Authenticated: アセットのオリジナル・変換画像ともにアクセスを制限

アクセスを制限した場合、実用例でも使われていた 署名付きURL(Signed URL)のような認証がなければアセットを表示することができません。署名付きURLは、冒頭の例の s--nJaC4tAU-- のように、ランダムな英数字の組み合わせです。アセットや変換の組み合わせから導き出されるため、固定の値を使い回すことはできません。

Private は、あらかじめ許可した変換しか表示できなくなる、Strict Transformationsをアカウントで有効にした場合に効果的です。

Cloudinaryの配信URLについて

Cloudinaryの配信URLは下記のような構成です。リソースタイプ・タイプは、デフォルトで画像をアップロードすると image/uploadとなり、いわゆるパブリックの状態です。上述の PrivateAuthenticated を使うと [タイプ] 部分が変わるため、画像URLのパスが変わります。

  • https://res.cloudinary.com/[クラウド名]/[リソースタイプ]/[タイプ]/[署名]/[変換パラメータ]/[バージョン]/[パブリックID].[フォーマット]
    • [クラウド名]: Cloudinaryアカウント名
    • [リソースタイプ] : image/raw/videoのいずれか
    • [タイプ] : upload(デフォルト)、privateauthenticatedfetchfacebookyoutubeなど(詳細はDelivery types

URLについて詳しくはこちらのブログを参照してください。

アクセスコントロールを適用した動きの違い

アクセスコントロールを適用した場合、メディアライブラリで確認してみると、デフォルト(Public)は地球儀、Privateは停止マーク、Authenticatedは南京錠のように、アイコン表示が区別されます。

以降では、次の画像を例に、Strict Transformations が有効/無効なケースそれぞれでの動きの違いを解説します。

  • オリジナル:https://~/image/upload/v1591379327/cafe.jpg
  • 変換後:https://~/image/upload/f_auto,w_300/v1591379327/cafe.jpg

デフォルトでアップロードした、パブリックでアクセス可能な画像 cafe で、変換パラメータに f_autow_300を適用しています。

※ "~" 部分は実際のパスを省略しています。
※ バージョンの有無は今回のアクセス制限には関係ないため、以降はバージョン表記を省略します。バージョンの詳細は Asset versions(英語ドキュメント)より。

Strict Transformations が無効な場合(デフォルト)

冒頭の説明にもある通り、Private はオリジナル、Authenticated はオリジナル・変換後とも、署名付きURLがなければアクセスができません。cafe のアクセスコントロールを変更した場合、それぞれ次のようなURLになります。

  • Private
    • オリジナル:~/image/private/s--SIGNATURE--/cafe.jpg
    • 変換後:~/image/private/f_auto,w_300/cafe.jpg
  • Authenticated
    • オリジナル:~/image/authenticated/s--SIGNATURE--/cafe.jpg
    • 変換後:~/image/authenticated/s--SIGNATURE--/f_auto,w_300/cafe.jpg

Private は変換後の画像であればパラメータ操作による即時変換が可能のため、変換パラメータを例えば o_100 などに置き換えることで実質オリジナルと見栄えが同じような画像が取得できてしまいます。そのため、Strict Transformations を有効にしないとあまり有用ではありません。

アカウントで Strict Transformations を無効のままでウォーターマークを適用させる場合には、アセットを Authenticated とするのが最適です。

Strict Transformations が有効な場合

Strict Transformations はアカウントレベルの設定で、有効にすると、事前に生成した変換画像を配信するか、事前に許可した変換のみを適用させられることになり、パラメータ操作による動的な変換はできず、他の変換には署名付きURLが必要となります。次の通り、設定の Security から「Enabled」に変更します。

これは変換アセットに関する設定のため、オリジナルへの挙動は変わらずPublicならアクセス可能、Private/Authenticated なら署名付きURLでなければアクセス不可です。一方、変換後の画像には Public/Private で Strict Transformations 有効化による制限がかかります。

  • Public
    • オリジナル:~/image/upload/cafe.jpg
    • 変換後(事前生成済み):~/image/upload/w_200/cafe.jpg
    • 変換後(事前許可済み):~/image/upload/f_auto/cafe.jpg
    • 変換後(その他):~/image/upload/s--SIGNATURE--/f_auto,w_300/cafe.jpg
  • Private
    • オリジナル:~/image/private/s--SIGNATURE--/cafe.jpg
    • 変換後(事前生成済み):~/image/private/w_200/cafe.jpg
    • 変換後(事前許可済み):~/image/private/f_auto/cafe.jpg
    • 変換後(その他):~/image/private/s--SIGNATURE--/f_auto,w_300/cafe.jpg
  • Authenticated
    • オリジナル:~/image/authenticated/s--SIGNATURE--/cafe.jpg
    • 変換後:~/image/authenticated/s--SIGNATURE--/f_auto,w_300/cafe.jpg

事前生成・事前許可の方法は次に示します。これらが済んでいれば、署名付きURLのような認証がなくても配信できます。済んでいない変換については、 Public/Private/Authenticated いずれでも署名付きURLが必要です。

アカウントで Strict Transformations を有効にしてウォーターマークを適用させる場合には、アセットを Authenticated とするか、もう少し柔軟に、許可された他の変換も適用させたい場合にはPrivate とするのが良いでしょう。

◆ 英語ドキュメント: Strict Transformations

事前に変換画像を生成する方法

変換画像を事前に生成するには、APIを使って eager オプションで生成する変換を指定します。

# アップロード時に変換を生成 (Upload メソッド)
cloudinary.uploader.upload("./test.jpg",
  public_id = "test",
  type = "private",
  eager = [
    "w_200",
    "w_100,h_200,c_fill"
  ])
# => 下記URLがアクセス可能に
# https://res.cloudinary.com/CLOUD-NAME/image/private/w_200/test.jpg
# https://res.cloudinary.com/CLOUD-NAME/image/private/w_100,h_200,c_fill/test.jpg

# 既存画像の変換を生成 (Explicit メソッド)
cloudinary.uploader.explicit("fol1/test2",
  type = "upload",
  eager = [
    "t_cm_logo"
  ])    
# => 下記URLがアクセス可能に
# https://res.cloudinary.com/CLOUD-NAME/image/upload/t_cm_logo/fol1/test2.jpg

コンソールでは、このようにアップロードごとに指定したり既存のアセットに対して変換を生成することはできませんが、アップロードプリセットの中で毎回生成する変換を定義しておくことができます。

なお、Cloudinaryにおける変換は、一般的には変換が初めて呼び出された時に行われます。これを "Lazy Transformations" と呼びます。逆に、上記のようにあらかじめ変換を生成する機能は "Eager Transformations" と呼びます。

◆ 英語ドキュメント: Eager Transformations

事前に変換を許可する方法

Strict Transformations が有効なアカウントでは、デフォルトではすべての変換が許可されていない状況です。特定の変換を許可するには、コンソールでは Transformations の一覧から対象の変換のマークをクリックします。緑のアイコンが許可済み、赤のアイコンが未許可の状態です。

Cloudinary allow strict transformations

API では以下のように allowed_for_strict オプションを有効にします。

cloudinary.api.update_transformation("f_auto",
  allowed_for_strict = True)

このように許可された変換は、前項のように事前に変換を生成(Eager Transformation)しなくても、また署名付きURLでなくても、どのアセットにも適用させて配信することができます。(ただし、Authenticated は常に署名付きURLが必要)

まとめ

挙動の違いを次の表にまとめてみました。

Cloudinary access control

ちなみに、この画像も次のようなパスで右下にウォーターマークを重ねています。

https://res.cloudinary.com/CLOUD-NAME/image/authenticated/s--3m0h4z5X--/f_auto,q_auto:best/c_scale,g_south_east,l_cm_logo,o_60,w_100,x_5,y_5/v1594304159/vkoxqig2m3bzz1r3azen.png

なお、今回は一律で署名付きURLが必要かどうかと記載しましたが、実際には認証にはトークンベース・クッキーベースの方法もあります。(※いずれもプレミアムのみ)また、時間制限付きでアクセス制限することも可能で、以下の関連ブログでやってみた様子が紹介されています。

◆ 英語ドキュメント: Authenticated access to media assets
◆ 英語ドキュメント: Providing time-limited access to private media assets
◆ 関連ブログ: Cloudinaryでアップロードしたメディアファイルのアクセスコントロールを試してみる | Developers.IO

次回は、Private/Authenticated への設定方法と署名付きURLの具体的な設定について解説します。

以上、ご利用いただく上で参考にしていただけると幸いです!


クラスメソッドはCloudinaryのパートナーとして導入のお手伝いをさせていただいています。お気軽にこちらからお問い合わせください。こちらから無料でもサインアップいただけます。