3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Nuxt3】認証付きの画像URLをimgタグで表示する方法

Last updated at Posted at 2024-02-14

画像URLに認証がついている場合、単純に <img src="https://...."> で画像を表示することはできません。

認証付きの画像URLをimgタグで表示したい場合は、下記手順で行います。

  1. fetch APIで認証付き画像URLにアクセスし、レスポンスボディをblobオブジェクトとして受け取る
  2. URL.createObjectURL で blobオブジェクトからオブジェクトURLを生成し、そのURLをimgタグのsrc属性に指定する

画像取得API

※ この例ではFastAPIを使っています

認証が必要な画像取得APIを準備します。
処理としてはS3から画像を取得して、StreamingResponseとして返すだけです。

@router.get("/images/{image_id}/")
def download_image(
    image_id: int,
    _current_user: User = Depends(auth.get_current_user),  # 認証の処理 (省略)
):
    s3_client = boto3.client("s3", region_name="ap-northeast-1")
    s3_bucket = "xxxxxxxxxxx"
    s3_key = f"path/to/image/{image_id}.png"
    obj = s3_client.get_object(Bucket=s3_bucket, Key=s3_key)
    return StreamingResponse(content=obj["Body"], media_type="image/png")

画像を表示

fetch APIで先程作成した画像取得API( /images/{image_id}/ )にアクセスして、imgタグで画像を表示します。

imgタグで表示

app.vue
<template>
  <div>
    <img :src="blobObjectUrl" width="500px" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const blobObjectUrl = ref<string>('dummy');
onMounted(async () => {
  const url = 'https://example.com/images/1/';
  // fetch API で認証付き画像URLにアクセス
  const res = await fetch(url, {
    method: 'GET',
    headers: { Authorization: `Bearer xxxxxxxxxxxxxxxxxxxxxx` },
  }).catch((err) => err.data);

  if (res.status == 200) {
    // レスポンスをblobとして受け取る
    const blob = await res.blob();
    // ブラウザのメモリ上に存在するblobオブジェクトを参照するためのURLを生成する。
    const objectUrl = URL.createObjectURL(blob);
    // オブジェクトURLをimgタグのsrc属性にセット
    blobObjectUrl.value = objectUrl;
  }
});
</script>

Nuxt Imageを利用して表示

※ Nuxt Imageのインストール: npm install @nuxt/image

app.vue
<template>
  <div>
    <!-- NuxtImg: https://image.nuxt.com/usage/nuxt-img -->
    <NuxtImg :src="blobObjectUrl" width="500px" />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const blobObjectUrl = ref<string>('dummy');
onMounted(async () => {
  const url = 'https://example.com/images/1/';

  // 認証付き画像URLにアクセス
  const res = await fetch(url, {
    method: 'GET',
    headers: { Authorization: `Bearer xxxxxxxxxxxxxxxxxxxxxx` },
  }).catch((err) => err.data);

  if (res.status == 200) {
    // レスポンスをblobとして受け取る
    const blob = await res.blob();
    // ブラウザのメモリ上に存在するblobオブジェクトを参照するためのURLを生成する。
    const objectUrl = URL.createObjectURL(blob);
    // オブジェクトURLをNuxtImgタグのsrc属性にセット
    blobObjectUrl.value = objectUrl;
  }
});
</script>
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?