sparna-git / Sparnatural

Sparnatural : Typescript visual SPARQL query builder for knowledge graphs, configurable with SHACL
http://sparnatural.eu
GNU Lesser General Public License v3.0
206 stars 34 forks source link

Provide the ability to add authorization headers to SPARQL endpoint in react #517

Closed PyHahiro closed 1 year ago

PyHahiro commented 1 year ago

Hello, I am trying to integrate Sparnatural in a react application with NextJS and my endpoint requires a private token, it is usually registred like this :

headers: {
        'Content-Type': 'application/json',
        "Authorization": `Bearer ${getAccessToken()}`
      }

I want to be able to access my endpoint with this kind of configuration :

 <spar-natural 
          ref={sparnaturalRef}
          src={sparnaturalConfigRoute}
          endpoint={endpoint}
          lang="fr"
          //queryLang="fr"
          distinct="true"
          limit="10"
          debug="true"
      ></spar-natural>

I want to use the given "endpoint" with headers in a way that would enable me to pass my authorization header.

I have not found in the documentation or in any topic related issues, something that would work as a workaround for my problem.

Is there anything I can do, thank you in advance

I use sparnatural 8.4.0

tfrancart commented 1 year ago

See https://github.com/sparna-git/Sparnatural/issues/448 - no solution yet, but we will raise the criticity of this issue By any chance, if you have a test SPARQL endpoint with which we could test, that would be helpful.

PyHahiro commented 1 year ago

I cannot provide my SPARQL endpoint myself but I may come back to you if i can.

I find a workaround for my situtation: Since my app is using nextJS to call my actual API. I did put my sparnatural endpoint on nextJS with a calling endpoint with parameters

components/sparnatural.tsx

<spar-natural 
          ref={sparnaturalRef}
          src={sparnaturalConfigRoute}
          endpoint={`/api/executeSparnaturalQuery?authorization=${getAccessToken()}`}
          lang="fr"
          //queryLang="fr"
          distinct="true"
          limit="10"
          debug="true"
      ></spar-natural>

with my endpoint being in nextJS and not requiring an authorization header when called from my component I can then,

pages/api/executeSparnaturalQuery.ts

const response = await (await fetch(request.url, {
      method: request.method,
      headers: {
        "Authorization": `Bearer ${params.token}`,
      } 
    })).json();
    res.status(200).json({error: false, message: 'Query response OK', results: {"bindings": response}})
tfrancart commented 1 year ago

Latest commit should allow you to set custom headers that will be passed in requests from list, autocomplete and tree widgets:

Set it like so:

sparnatural.addEventListener("init", (event) => {
  sparnatural.headers = {
    "User-Agent" : "This is Sparnatural calling"
  };
});

Would you be able to give it a try ?

PyHahiro commented 1 year ago

Could you provide a way of testing sparnatural locally ? I was using sparnatural 8.4.0 and tried to clone the project then add it to my react dependencies in package.json :

"devDependencies": { ... "sparnatural": "file:../../Sparnatural" }

but my application can't find modules the same way it used to do using the packaged version of sparnatural. Is there a Documentation I am missing ?

Regardless, thank you for your quick answer and implementation, that is really appreciated

tfrancart commented 1 year ago
  1. clone the project
  2. run npm install to install dependencies
  3. run npm run start to start the dev server
  4. customize dev-page/index.html as needed
PyHahiro commented 1 year ago

I have tested it and it seems to works just fine, I tried with Authorization header and even only with User-Agent

image

sparnatural.addEventListener("init", (event) => {
  sparnatural.headers = {
    "User-Agent" : "This is Sparnatural calling",
    "Authorization" : "Bearer token"
  };
});
PyHahiro commented 1 year ago

Hello, I just find out that my workaround is forcing my component to reload, because either" src" to get config or "endpoint" to use widgets, is being reloaded when my token changes. Don't you mind make a mini release in order for me to use this fix asap ? I don't mind waiting but I still wanted to ask if possible, thank you

PyHahiro commented 11 months ago

Hello, last release worked great but I think there is still something to work on about this header thingy, when creating a component in react

<spar-natural
            ref={sparnaturalRef}
            src={`<config/endpoint>`}
            endpoint={`<api/endpoint>`}
            lang="fr"
            //queryLang="fr"
            distinct="true"
            limit="-1"
            debug="false"
></spar-natural>

Since src is calling the config/endpoint at initialization, the code bellow is not yet executed

sparnatural.addEventListener(
          "init",
          (event: SparnaturalEvent) => {
            sparnatural.headers = {
              "Authorization": `Bearer ${getAccessToken()}`
            }
          }
        );

making it work only for api call on endpoint but not when getting the sparnatural configuration, I think the expected behavior would be for the configuration to be able to use the header once set

tfrancart commented 11 months ago

Ha yes, you are absolutely right, headers are not passed on the loading of the configuration itself. I will open a separate issue for this. @PyHahiro you seem to have a good experience in integrating Sparnatural with React, if you could review/enhance the documentation at https://github.com/sparna-git/Sparnatural/blob/master/docs/react-integration.md (I don't know React myself). Also, please see new "getting started" documentation at http://docs.sparnatural.eu/hello-sparnatural/Hello-Sparnatural.html