makenotion / notion-sdk-js

Official Notion JavaScript Client
https://developers.notion.com/docs
MIT License
4.93k stars 586 forks source link

blocked by CORS policy #96

Closed JoarGjersund closed 3 years ago

JoarGjersund commented 3 years ago

I am trying to talk to the notion api via a webpage, but it is getting blocked by the browser. I think this should be possible to fix on the server side by adding the "Access-Control-Allow-Origin: *" in the reply header.

A current workaround for this is to run the browser with CORS check disabled.

alicial commented 3 years ago

Hi @JoarGjersund, we currently don't support CORS and don't recommend making API calls from a web page.

hacknug commented 3 years ago

A current workaround for this is to run the browser with CORS check disabled.

This will work as long as you're the only user. Anyone else who hasn't disabled that option won't be able to get the results. Pretty sure you don't expect users to disable it and you're aware of the security concerns that come with it.

In case you still need to work around the issue, I'd recommend deploying something like cors-anywhere to one of your servers. Not the best solution but it's been super helpful to have around when I've needed to deal with this type of situations.

JoarGjersund commented 3 years ago

Thanks for the reply guys! I was hoping it would be possible to make API calls on client side from static webpage without setting up a server and configuring to much back-end stuff, but I guess that won't be possible without at least setting up a cors proxy server.

yassinebridi commented 3 years ago

I'm not sure which framework you are using, or if is just Html and CSS, but consider using something like Next.js or Nuxt.js, as I'm doing with Next.js everything is static, and you wouldn't have this issue. A second option as stated above is using a proxy, for this, I would suggest using Cloudflare workers, I already have something like that setup here: https://cors.yasbr.com I suggest deploying your own using this repo: https://github.com/yassinebridi/cors There is no documentation yet, but just read on Cloudflare workers, and how to set up deployment using Github actions.

JoarGjersund commented 3 years ago

I am just using the simplest of the simple javascript, fetching the auth key and database via GET. Here is my initial test code where I'm inserting some test data to a table in notion.

<html>
<head>
<script>

const urlParams = new URLSearchParams(window.location.search);

var database = urlParams.get('db')
var auth = urlParams.get('auth')

const data = {
    "parent": { "database_id": database },
    "properties": {
      "Name": {
        "title": [
          {
            "text": {
              "content": "test, test2"
            }
          }
        ]
      }
    }
  };

function loadDoc() {

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
  document.getElementById("demo").innerHTML = this.responseText;
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML = this.responseText;
    }
  };
  xhttp.open("POST", "https://api.notion.com/v1/pages", true);
  xhttp.setRequestHeader("Authorization", "Bearer " + auth);
  xhttp.setRequestHeader("Content-type", "application/json");
  xhttp.setRequestHeader("Notion-Version", "2021-05-13");

  xhttp.send(JSON.stringify(data));

}
</script>
</head>
<body>

<h1>The XMLHttpRequest Object</h1>

<p id="demo"></p>
 <button type="button" onclick="loadDoc()">Request data</button>
</body>
</html>
spyderdsn commented 3 years ago

I'm not sure which framework you are using, or if is just Html and CSS, but consider using something like Next.js or Nuxt.js, as I'm doing with Next.js everything is static, and you wouldn't have this issue. A second option as stated above is using a proxy, for this, I would suggest using Cloudflare workers, I already have something like that setup here: https://cors.yasbr.com I suggest deploying your own using this repo: https://github.com/yassinebridi/cors There is no documentation yet, but just read on Cloudflare workers, and how to set up deployment using Github actions.

Hi @yassinebridi is it just me or your worker solution does not work?

https://cors.yasbr.com/https://api.notion.com/v1/databases/[DBID_HERE]

Thanks

Xheldon commented 3 years ago

I think the problem can be solved by just adding a whitelist to the configuration page of the Notion Integration, indicating the domains under which the secret can be called, what is the reason for not doing so? Is it because there will be a lot of asynchronous requests from the web page that will burden the server?

doesDesign commented 2 years ago

I was trying to build out some cool stuff in codepen hooking into the Notion API and I ran into this same problem. bummer!! I'm hopeful you will add some kind of whitelist support soon. Full disclosure - I am a designer (working in design systems) and not a dev, so my use cases will be a bit different.

doesDesign commented 2 years ago

Hi @alicial / Notion - now that the API is out of beta, do any of the new updates enable this kind of functionality? I'm hoping now I can hook into the API from a webpage, and/or a Figma plugin I'm building.

KevinKZ commented 2 years ago

Hi @alicial / Notion - now that the API is out of beta, do any of the new updates enable this kind of functionality? I'm hoping now I can hook into the API from a webpage, and/or a Figma plugin I'm building.

I second this! I am trying to make calls to the API from notion.so/user/page/xxxxxx to implement 'custom' commands and being blocked by CORS

danielcharrua commented 2 years ago

Hello, you could use a worker from Cloudflare to proxy your requests to the notion API: https://developers.cloudflare.com/workers/examples/cors-header-proxy/

KevinKZ commented 2 years ago

Hi! I've been exploring this idea as a workaround, thank you. Was also thinking of using JSONP so that other users don't have to create a proxy too. Is that a feasible solution in your opinion?

danielcharrua commented 2 years ago

I don't see how using JSONP for posting data to Notion API will work, please share your solution.

naveenbharadwaj19 commented 2 years ago

https://github.com/makenotion/notion-sdk-js/issues/96#issuecomment-898989814

Not working.Even though i tried setting up my own worker https://<my-domain>/https://api.notion.com/v1 same CORS issue. Any solution?

kalaomer commented 1 year ago

Hello guys, I wrote my worker because of some issues. You can implement to your side easily, here it is;

const API_END_POINT = "https://api.notion.com/v1";

export default {
  async fetch(request, env) {
    return await handleRequest(request)
  }
}

function getCorsHeaders(request) {
  return {
    "Access-Control-Allow-Origin": request.headers.get("Origin"),
    "Access-Control-Allow-Methods": "GET, HEAD, POST, PUT, OPTIONS",
    "Access-Control-Allow-Headers": "Content-Type",
  };
}

function handleOptions(request) {
  return new Response(null, {
    headers: getCorsHeaders(request),
  });
}

async function handleRequest(request) {
  if (request.method === "OPTIONS") {
    return handleOptions(request);
  }

  let url = new URL(request.url);

  let requestUrl = `${API_END_POINT}${url.pathname}`;

  let notionResponse = await fetch(requestUrl, {
    body: request.body,
    headers: {
      "Authorization": "Bearer SECRET_KEY",
      "Notion-Version": "2022-06-28",
    },
    method: request.method
  });

  return new Response(notionResponse.body, {
    headers: {"Content-Type": "application/json", ...getCorsHeaders(request)},
    status: notionResponse.status,
    statusText: notionResponse.statusText
  });
}

Change SECRET_KEYvalue with yours

emdax commented 1 year ago

I think the problem can be solved by just adding a whitelist to the configuration page of the Notion Integration, indicating the domains under which the secret can be called, what is the reason for not doing so? Is it because there will be a lot of asynchronous requests from the web page that will burden the server?

Any practical reason to not enable this sweet solution?

Phylo229 commented 1 year ago

@kalaomer be careful embedding secret keys directly in your worker code. Use wrangler references instead:

https://stackoverflow.com/questions/69018567/cloudflare-workers-security-and-visibility#:~:text=Nobody%20outside%20Cloudflare%20will%20be,to%20them%20in%20your%20code.

kalaomer commented 1 year ago

@Phylo229 thanks for warning, i will update my worker :)

scv057 commented 1 year ago

Any updated?

eldang commented 5 months ago

I've run into the same problem, and it seems really odd to have a JavaScript SDK and then say in an issue that it shouldn't used from the browser. If that's really the intention, it would be worth making that explicit in the README so that people don't waste time having to find this thread.

david1542 commented 4 months ago

@eldang agree, it's super weird. I was also interested in querying notion api from a web page.

It should be stated somewhere.

jdbohrman commented 4 months ago

@david1542 Makes zero sense to me haha

nyrsimon commented 2 months ago

This is just bizarre - you can't build a web app that can access Notion - am I understanding that correctly? You need to build some kind of back end?

david1542 commented 2 months ago

@nyrsimon that's correct. At the moment, you can't make HTTP requests from a JavaScript in the browser. You need to do that from a server.

eldang commented 2 months ago

I think I do now understand why it's done this way. Even if a user just sniffs the API responses using Developer Tools, they would be able to construct additional requests that get more information than a given app is displaying, so there's a pretty big data leak risk (and potentially also vandalism risk if the permissions aren't locked down enough) to having the requests be visible to the client at all.

But the number of people commenting here tells me I'm not crazy for seeing "JavaScript SDK" and thinking I would be able to use it in the browser. I expect server-only SDKs to be written for PHP, Golang, Python, etc. I think it would be worth putting an explicit qualifier early in this SDK's README, and in the Notion docs where they reference the JS SDK. That could save a lot of people from wasting time trying to make this work in a way it's not intended to.

Xheldon commented 2 months ago

You can use notion js sdk in browser extension,not only in backend,see what i do: https://notion-flow.xheldon.com/en/