openai / openai-node

The official Node.js / Typescript library for the OpenAI API

Home Page:https://www.npmjs.com/package/openai

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Refused to set unsafe header "User-Agent"

AmanKishore opened this issue · comments

Getting this error when trying to run the following code:
Refused to set unsafe header "User-Agent"

const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
const response = await openai.createCompletion("code-davinci-001", {
  prompt: filePart,
  temperature: 0.1,
  max_tokens: 2000,
  top_p: 1,
  frequency_penalty: 0,
  presence_penalty: 0.5,
});

Is there a way to remove the User-Agent error

@AmanKishore this error occurs if we call OpenAI from the frontend / client-side instead of the secure backend / server-side.

I am working on a front-end internship challenge and so I am trying to purposefully call OpenAI from the frontend as this was the challenge. Is there still no solution or workaround to this?

@rickstylz01 Here's the workaround I used:

      const requestOptions = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': 'Bearer ' + String(openAIKey)
        },
        body: JSON.stringify({
          'prompt': prompt,
          'temperature': 0.1,
          'max_tokens': Math.floor(fileLength/2),
          'top_p': 1,
          'frequency_penalty': 0,
          'presence_penalty': 0.5,
          'stop': ["\"\"\""],
        })
      };
      fetch('https://api.openai.com/v1/engines/code-davinci-001/completions', requestOptions)
          .then(response => response.json())
          .then(data => {
            # Do something with data
        }).catch(err => {
          console.log("Ran out of tokens for today! Try tomorrow!");
        });
    }

I'm also using this in the context of an electron desktop app and am getting this error.

I'm planning on opening a PR to add an option to exclude explicitly adding the user-agent, and letting the browser set it itself.

https://stackoverflow.com/questions/33143776/ajax-request-refused-to-set-unsafe-header

Please do not use this library in the browser, it is not secure – people will be able to steal your API key. See README.md:

Important note: this library is meant for server-side usage only, as using it in client-side browser code will expose your secret API key. See here for more details.

You should route your requests through a backend server that you control.

@schnerd What if I'm using a framework like electron to build desktop apps? I'll get the same error and there is no server side I could move the call to...

You can use Nitro Server inside Nuxt3 to properly handle the request without revealing API key.

const setRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function newSetRequestHeader(key: string, val: string) {
    if (key.toLocaleLowerCase() === 'user-agent') {
        return;
    }
    setRequestHeader.apply(this, [key, val]);
};

You can ignore the user-agent settings

this line worked for me

let configuration = new Configuration({
  organization:"org-asd",
  apiKey: "sk-asd",
});

delete configuration.baseOptions.headers['User-Agent'];

const openai = new OpenAIApi(configuration);

@schnerd what if I have a BE proxy that sets the API key? Being able to use this library in the browser without providing an API key would be beneficial. Please consider that setting the user agent is a user space responsibility.

this is just some thoughts that I want to share.
i'm not targeting to anyone. if i did i'm apologizing.
chatgpt is great. i used it a lot and it help me tremendously.

here goes

if I build an app that allows my users to chat with openai, is it more safe to relay all their private chat through me? or let them use the client to talk directly to openai api? keeping key on server is a common practice i know (everyone knows) but it's not some rules made by the God. And my solution to this is to run a local server (just 5 lines of code and also runs on my user's computer). and this is more safe? it's ALWAYS safer to cut all the middle man, no server is better than the best server. btw, server is more secure? it's hundres of servers in a location where I don't have access to, and the safety rely purely on the datacenter staff and i know them a lot. server doesn't have data breach incidents? they do have vlans and common way to seperate but s**t happens, i've went thru them a lot...

and even it's true that it should be used in a server env only, you can't (shouldn't) prohibit people from using it in the client environment. The only thing you did was not allowing your devs to change user-agent, which is what? allowing them to change the user-agent setting will do what harm? To a lot of people, losing a key vs trusting their all chat records to some unknown provider (like me), what do you think they prefer? what is more important? the chat logs or a openai key? it might be more important to openai that the keys are kept secret so it won't cause a lot of requests by malicious parties who steal keys online. i understand that. but don't use this as an excuse.
some advices

  • you can tell people to use this in a server env. it's a recommendation. not a law.
  • if devs need to use this in a client env, you should find a way to provide them necessary means to remove user-agent header. it's not that hard.
  • even better, you should find a way to allow pure client app to login instead of using an api key.

im getting the same error here
here is my code :

import { Configuration, OpenAIApi } from "openai";

// Api key will not work for you
const OPENAI_API_KEY = (${(import.meta.env.VITE_REACT_APP_API_KEY)});

const configuration = new Configuration({
apiKey: OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

export async function sendMessageToOpenAI(message) {
const response = await openai.createCompletion({
model: "text-davinci-003",
prompt: message,
temperature: 0.9,
max_tokens: 256,
top_p: 1,
frequency_penalty: 0,
presence_penalty: 0,
});
return response.data.choices[0].text;
}

Hi @AmanKishore and others – just as an an FYI, we have a new, fully-rewritten upcoming v4 of the SDK that has better browser support out of the box. You can give it a try with npm install openai@v4.0.0-beta.4

Note that we expect to require a config option like dangerouslyAllowAPIKeyInBrowser: true for this use-case in the near future.

@yangxin9003 that answer is pretty evil. I love it.

To all who land here, heed @schnerd's warning.

Unless you're doing class-work you need to use a server that you control to route your api calls through. Otherwise, your credit card is going to get murdered with fees. You don't want to go bankrupt do you?