Skip to content

"Error: A Cloudinary API Key is required for signed requests, please make sure your environment variable is set and configured in your environment." #241

@tmorgan497

Description

@tmorgan497

I'm running into an issue getting the CldUploadWidget to work in signed mode. On the client side I have:

                <ClientOnly>
                    <CldUploadWidget
                        v-slot="{ open }"
                        uploadPreset="test"
                        signatureEndpoint="/api/products/get_cloudinary_signature"
                    >
                        <Button label="Upload an Image" @click="open" />
                    </CldUploadWidget>
                </ClientOnly>

and my backend endpoint I have:

// server/api/products/get_cloudinary_signature.ts

import { v2 as cloudinary } from "cloudinary";

export default eventHandler(async (event) => {
    const config = useRuntimeConfig();

    const body = await readBody(event);

    console.log("Request Body:", body);
    console.log("Backend Secret:", config.CLOUDINARY_API_SECRET);

    if (!body || !body.paramsToSign) {
        console.error("Missing paramsToSign in request body.");
        throw createError({
            statusCode: 400,
            statusMessage: "paramsToSign is required.",
        });
    }

    const signature = cloudinary.utils.api_sign_request(
        body.paramsToSign,
        config.CLOUDINARY_API_SECRET,
    );

    console.log("Generated Cloudinary Signature:", signature);

    return { signature };
});

When i manually get the signature from the endpoint, it works fine. The console logs show the api secret and the resulting signature

<template>
                <Button
                    label="Get Cloudinary Signature"
                    @click="printCloudinarySignature"
                />
</template>

<script setup lang="ts">
async function printCloudinarySignature() {
    console.log("Cloudinary API Key:", config.public.cloudinary.apiKey);
    try {
        const timestamp = Math.floor(Date.now() / 1000);
        const paramsToSign = {
            timestamp: timestamp,
            folder: "products",
        };

        const response = await $fetch("/api/products/get_cloudinary_signature", {
            method: "POST",
            body: {
                paramsToSign,
            },
        });
        console.log("Cloudinary Signature:", response.signature);
    } catch (error) {
        console.error("Error fetching Cloudinary signature:", error);
    }
}
</setup>

But the error I'm getting from the widget says I need to set my api key. But i've already verified that the key is setup and working with the debugging code above. Here's my nuxt config:

export default defineNuxtConfig({
    devtools: { enabled: true },
    future: {
        compatibilityVersion: 4,
    },
    runtimeConfig: {
        public: {
            CLOUDINARY_CLOUD_NAME: process.env.CLOUDINARY_CLOUD_NAME,
            CLOUDINARY_API_KEY: process.env.CLOUDINARY_API_KEY,
        },
        CLOUDINARY_API_SECRET: process.env.CLOUDINARY_API_SECRET,
    },

    modules: [
        "@nuxtjs/cloudinary",
    ],

    cloudinary: {
        cloudName: process.env.CLOUDINARY_CLOUD_NAME,
        apiKey: process.env.CLOUDINARY_API_KEY,
        uploadPreset: "test",
    },

});

It's probably a simple mistake, but I can't for the life of me figure out how to get it to work properly. I've tried unsigned mode and it works fine, but I'd like to use signed mode for better access control.

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions