Authorize Masterdata API call from react (admin) to node to masterdata

Hi there,

I need to make some endpoints private on node, at the moment I’m in a homologation process of publishing the app and I need to make creation/edit/delete endpoints private so other users can’t call or access them without credentials essentially.

I’m told on the thread to use Authorization header using
https://app.io.vtex.com/{{vendor.app_name}}/v0/{{VTEX_ACCOUNT}}/{{WORKSPACE}}/_v/ENDPOINT_URL

curl 'https://app.io.vtex.com/{{vendor.app_name}}/v0/{{VTEX_ACCOUNT}}/{{WORKSPACE}}/_v/list-embeds' \
--header 'Content-Type: application/json' \
--header 'Cache-Control: no-store, max-age=0' \
--header 'Authorization: {{TOKEN}}'

manifest.json

{
      "name": "outbound-access",
      "attrs": {
        "host": "app.io.vtex.com",
        "path": "*"
      }
    },

As I understood this TOKEN is VtexIdclientAutCookie on the header which we extract from ctx.vtex.authToken

I’m calling from the vtex react app the URL represented above and it gives me CORS 401 error, also I tried to implement it directly into node but this doesn’t seem a good solution because I have to set it into communication between vtex react app (admin) to node (vtex server side) which communicates with masterdata.

Tried to call the same API from Postman and it says [my email] doesn’t have access to the GET resource and it outputed the vrn: address from AWS, I’ve got Super Admin access and I’ve checked that all the resources on this role are available.

Can you please help me on this? Maybe anyone of you encountered this problem?

Thank you in advance,

Hello!

I have a question, does the request fail inside one of your middlewares for that endpoint? Or it fails before that?

Maybe is something related to the endpoint itself, the one you declare inside your service.json.
When a REST endpoint is private you should declare the policies for it. Here is an example:

"myPrivateRoute": {
      "path": "/_v/myPrivateRoute",
      "public": false,
      "access": "authorized",
      "policies": [
        {
          "effect": "allow",
          "actions": ["get"],
          "principals": ["vrn:apps:*:*:*:app/{{vendor.frontend_app_name}}@*"]
        }
      ]
    }

In the example above, that private endpoint is declared in my node app and the only thing that can access that endpoint with a GET request is my frontend app (declared with the VRN in the principals)

Let me know if this works! :smile:

3 Likes

Hi Gabriel,

I’ve tried to set the police you’ve sent and it didn’t work, it kept saying Forbidden, I’ve tried to change the form of principals as it is written inside the error and no luck, tried both ways.

Hello again,

I belive that the token you are trying to use may not be the right one. I think that the token you are using is related to you as a client of the store and not as the one as an admin (not sure tho :thinking:)

I suggest you try this:

  1. Try making that request without the Authorization (removing that param you send) to see if the error persists.
  2. We can test the token, try to make the request with the VtexIdclientAutCookie , you can find that token in the cookies after you login into the admin.
1 Like

Yes, that’s the one (VtexIdclientAutCookie) I’m using from the cookie, from the app client (react),
the browser just says CORS error 401:

that’s the output from Postman:

Console output:

I was able to call the endpoint on postman now that i saw the complete URL

I did two things:

  1. I got the token from the cookies in the admin
  2. My header is not Authorization i sent VtexIdclientAutCookie
1 Like

Nop, it didn’t work in any circumstances, whether I set in the header VtexIdclientAutCookie or Authorization, it gives me CORS 401 error.

Having in node/service.json

"token": {
      "path": "/_v/token",
      "public": false,
      "access": "authorized",
      "policies": [
        {
          "effect": "allow",
          "actions": ["get", "post", "delete", "options"],
          "principals": [
            "vrn:apps:*:*:*:app/productleadpartnerro.productlead@*"
          ]
        }
      ]
    }
1 Like

That’s weird. You got that token today? Because i just did what i told i the last message.

The request returned a json with these fields: id, email, access_token, refresh_token, expire_at and created_at

1 Like

Yes, I even logged off and logged in again

Output from the app, I’m running the app on workspace productlead, means I’ve got https://productlead--productleadpartnerro.myvtex.com of the store and https://productlead--productleadpartnerro.myvtex.com/admin/productlead from the app (admin)

Output of the private endpoint

Can you try using ctx.vtex.adminUserAuthToken? I saw that you were using the ctx.vtex.authToken, maybe that could be the reason.

And the header key i belive it should still be VtexIdclientAutCookie

1 Like

I’ve got a middleware where I’ve tried both authToken and adminUserAuthToken…no luck

export async function getTokenMiddleware(
  ctx: Context,
  next: () => Promise<void>
) {
  const {
    vtex: { adminUserAuthToken },
    clients: { masterData, session },
    cookies,
  } = ctx
...
  try {
    const res = await masterData.getToken(ctx, {
      VtexIdclientAutCookie: adminUserAuthToken,
    })
...
}

BUT I’ve tried to set on axios header from rect { withCredentials: true } and somehow I’ve got an update from 401 error saying that * I should use something different from *
what can I set? having this:

"token": {
      "path": "/_v/token",
      "public": false,
      "access": "authorized",
      "policies": [
        {
          "effect": "allow",
          "actions": ["get", "post", "delete", "options"],
          "principals": [
            "vrn:apps:*:*:*:app/productleadpartnerro.productlead@*"
          ]
        }
      ]
    }

output console

Hold on, does the request fails inside your middleware? Or before that? Because i was thinking that it failed before the middlewares.

It’s failing before middleware, if I will pass service.json I’ll get into middleware and will get as output consoles in terminal, but it doesn’t happen

It’s failing right on CORS between node gate and react gate

CORS policy: Response to preflight request doesn’t pass access control check: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard '’ when the request’s credentials mode is ‘include’*

Update I saw some requests having 200 OK, have you tried on these timings?

So when i told you to use the VtexIdclientAutCookie it was in the axios request header. I think that is the problem, and not your middleware.

Update: Yes, the 200 request was me testing

1 Like

Yes I’m using them, I even hardcoded them :face_with_monocle::

export async function getToken(): Promise<any> {
  return await axios.get(
    `${API_VTEX_IO('productleadpartnerro', 'productlead')}/_v/token`,
    {
      headers: {
        VtexIdclientAutCookie: 'eyJhbGciOiJFUzI1NiIsImtpZCI6IkQxMzBGNDkxRjY5ODcyQUJ...'
      },
      withCredentials: true
    }
    ).catch(console.error)

Ok, try changing that to get that value from the cookie instead of using it hardcoded because that token can expire.

If that wont work i’m out of ideias here :slightly_frowning_face:

thanks anyway, I’m continue to debug, will post here if I find anything

1 Like

Hi there!

Have you tried to call http://productlead-productleadpartnerro.myvtex.com/_/token instead app.io.vtex.com ?

Just a wild guess: Try to add user:xx.xxx@productlead.me in the principals. I am sure it´s not going to work in production, but might work with Postman.

Hi Saito,

When I call with productlead–productleadpartnerro… it says that endpoint is not found (404), tried to use user in principals and nothin changed in postman nor in react client

Update: If I set principals: ["*"] it works from POSTMAN to request, but it doesn’t work inside vtex admin to request, it keeps the CORS error

Found the problem with the CORS. Try withCredentials: false

Explanation:

Hope this helps!