RayOkaah / woocommerce

Woocommerce SDK for Flutter. The Complete Woo Commerce SDK for Flutter.
BSD 3-Clause "New" or "Revised" License
121 stars 110 forks source link

Missing the X-WC-Store-API-Nonce header. This endpoint requires a valid nonce. #7

Open StarkSoftware opened 4 years ago

StarkSoftware commented 4 years ago

Hi i have this issue.

Did i must install some plugin or change settings on my woocommerce ?

The libs i the 0.9.6

Tnk's

RayOkaah commented 4 years ago

What is the endpoint being called?

StarkSoftware commented 4 years ago

POST https://www.mysite.com/wp-json/wc/store/cart/items

{"code":"woocommerce_rest_missing_nonce","message":"Missing the X-WC-Store-API-Nonce header. This endpoint requires a valid nonce.","data":{"status":401}}

RayOkaah commented 4 years ago

I can see this is a woo commerce error, but the cart management is not handled by woocommerce, as it has no means of handling that, so you should not be getting any woocommerce related error on cart. Which of the plugin's function was called?

StarkSoftware commented 4 years ago

Hi, my issue is this : https://github.com/RayOkaah/woocommerce/issues/2 Your wrote that is solved in 0.9.5 but for me not work

StarkSoftware commented 4 years ago

Hi, nothing to do. It’s not work. I have the nonce key with the library that you have send me, I add on headers but now I receive invalid nonce.

Did you have a sample code to fix this issue ?

RayOkaah commented 4 years ago

Hi. Pls share code. Adding to cart does not use woocommerce api. So a woocommerce auth error is unlikely.

FirasAjjour commented 4 years ago

Hi I am sorry it's my bad, the solution is based on WooSignal extension on WooCommerce, which is a paid service, by using this service i got the nonce and send it to the method in WooCommerce api, but i am still looking to find something can help to fetch nonce from wordpress. btw all founded method used some javascript libraries for that, i cannot find the url to get the generated nonce.

themumy10 commented 4 years ago

Is this issue resolved with new update?

themumy10 commented 4 years ago

I m still getting {"code":"woocommerce_rest_missing_nonce","message":"Missing the X-WC-Store-API-Nonce header. This endpoint requires a valid nonce.","data":{"status":401}} error In your code we are posting a request but header section only contains Auth data which is Bearer djksajlkdjlskajdlka But server asks us to send : X-WC-Store-API-Nonce data which is created by server side. We need this nonce data. and send it to server. I tried addto mychart method with 0.9.7 but still having this issue. Note i m logging in with a pre-created user with wordpress.

tavindersingh commented 4 years ago

Did anyone found the solution for this?

themumy10 commented 4 years ago

Not yet sorry. We need nonce data from server. To achieve this i guess we must write a function to functions.php manually. wp_create_nonce() function is what we need. But i dont know how

akfaisel commented 4 years ago

I too stuck at this error :(

akfaisel commented 4 years ago

It looks like the endpoint /wp-json/wc/store/cart/items does not exist. Is it possible to integrate with co-cart plugin - https://wordpress.org/plugins/cart-rest-api-for-woocommerce/?

I tried with Postman and it is working. But I don't have an idea to link it with this woocommerce flutter plugin.

akfaisel commented 4 years ago

According to this documentation https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/a404e5b24814240f15e50aa4f983b787bb9b36f1/src/StoreApi/docs/cart.md#add-item, nonce token needs to be included with the header. It can be generated by wp_create_nonce( 'wc_store_api' ) but I don't have any idea to do this. I'm a new born WP user, just 1 week old :).

nsubash38 commented 4 years ago

I am having the same issue. Please help !

yashz05 commented 4 years ago

https://github.com/RayOkaah/woocommerce/issues/26#issuecomment-712208270

siman302 commented 3 years ago

I have the same issue, anyone there who can solve it. Or there is another way to do it.

satya-prakash-dash commented 3 years ago

"message": "Missing the X-WC-Store-API-Nonce header. This endpoint requires a valid nonce.", "data": { "status": 401 } I still facing this problem , After showing this issue I put X-WP-Nonce - WPAPI.nonce in the header but still get the same problem . If any one have the solution then please comment here.

andreyc0d3r commented 3 years ago

The reason why you are seeing the error is due to API requiring not just any nonce, but a specific one.

Don’t just pass the value return from wp_create_nonce(‘my-string’), the value has to come from wp_create_nonce( ‘wc_store_api’ )

you can read more about it here:

https://digitalapps.com/woocommerce-rest-api-cart-endpoint-error/

anishmjn3 commented 3 years ago

getxwcStoreAPINonce = () => {

const { item, token, billing, shipping } = this.props.route.params;

axios({
  method: "POST",
  url: `${apiUrl}wp-json/wc/store/checkout?consumer_key=${consumerKey}&consumer_secret=${consumerSecret}`,
  headers: {
    "Authorization": "Bearer " + token,
  },

  data: {
    "billing_address": billing,
    "shipping_address": shipping,
    "payment_method": "bacs"
  },
  dataType: "json",
  contentType: "application/json; charset=utf-8",
  complete: function (response) {
  }
}).
  then((res) => {
    { console.log(item) `}`
  })
  .catch((err) => {
    this.setState({ XWCSTOREAPi: err.response.headers["x-wc-store-api-nonce"] })
    this.setState({ apikeyfound: false })
  })

}

checkout = (billing, shippping, token, navigation) => {

axios({
  method: "POST",
  url: `${apiUrl}wp-json/wc/store/checkout?consumer_key=${consumerKey}&consumer_secret=${consumerSecret}`,
  headers: {
    "Authorization": "Bearer " + token,
    "X-WC-Store-API-Nonce": this.state.XWCSTOREAPi,
  },
  data: {
    "billing_address": billing,
    "shipping_address": shippping,
    "payment_method": payment_method[this.state.payment],
    },
  dataType: "json",
  contentType: "application/json; charset=utf-8",
  complete: function (response) {
    console.log(response);
  }
}).
  then((res) => {
    console.warn(res);
    if (this.state.payment == 1) {
      navigation.navigate("KhaltiVerfication", { item: res.data, token: token })
    }
    else
      Alert.alert(
        "Successful",
        "Your Order has been placed",
        [
          {
            text: "OK",
            onPress: () => { navigation.navigate('Home'); },
            style: "cancel",
          },
        ]
      )
  })
  .catch((err) => {
    Alert.alert(
      "Error!!",
      "Your Order has not been placed",
      [
        {
          text: "OK",
          style: "cancel",
        },
      ],
      {
        cancelable: true,
      },
    )
    console.warn(err);
    console.warn(err.response.data)
    console.log("Response Status:", err.response.status);
    console.log("Response Headers:", err.response.headers);
  })

}

I used this way ko solve this missing problem. But now I am getting some other errors.

iNahvi commented 3 years ago

35

26

I have noticed, this issue while using this sdk. and after several searches . going through almost all the forked versions of this sdk. it seems some have tried to fix the nonce issue , by either generating a nonce and sending it , or trying to get it from storeapi but to non existing routes. So after going through the original source codes of the storeApi by

https://github.com/woocommerce/woocommerce-gutenberg-products-block.

I found that in the

woocommerce-gutenberg-products-block/src/StoreApi/Routes/AbstractRoute.php in the code when a get request is made to /wp-json/wc/store/cart/

it would send a response header with X-WC-Store-API-Nonce Created.

if ( 'GET' !== $request->get_method() && ! is_wp_error( $response ) ) { $response->header( 'X-WC-Store-API-Nonce', wp_create_nonce( 'wc_store_api' ) ); } https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/a404e5b24814240f15e50aa4f983b787bb9b36f1/src/StoreApi/Routes/AbstractRoute.php#L80-L82

After sending requests to the api route /wp-json/wc/store/cart/ through an Api client . it returns as this

parts of the header x-content-type-options: nosniff; nosniff access-control-expose-headers: X-WP-Total, X-WP-TotalPages, Link access-control-allow-headers: Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type expires: Wed, 11 Jan 1984 05:00:00 GMT cache-control: no-cache, must-revalidate, max-age=0 x-wc-store-api-nonce: 56f237XXXX x-wc-store-api-nonce-timestamp: 1625559263 x-wc-store-api-user: 1 allow: GET x-frame-options: SAMEORIGIN x-xss-protection: 1; mode=block

if I made a plain Get request to https://yoursite.com/wp-json/wc/store/cart/ it would reply with x-wc-store-api-nonce: XXXXXXXX x-wc-store-api-nonce-timestamp: XXXXXXXX x-wc-store-api-user: 0 x-wc-store-api-user: 0 in reference to an unregistered user .

As the api accepts Authorization header access-control-allow-headers: Authorization, X-WP-Nonce, Content-Disposition, Content-MD5, Content-Type sending the JWT bearer token _urlHeader['Authorization'] = 'Bearer ' + _authToken!; would return the logged in user's cart with its existing x-wc-store-api-nonce: XXXXXXX

to make calls to POST /cart/add-item POST /cart/remove-item POST /cart/update-item....

you can initialize the cart 1st by capturing the Get response header from a call to https://yoursite.com/wp-json/wc/store/cart/ Using your JWT bearer token and retrieving the x-wc-store-api-nonce and using it to make future calls to the StoreApi .

this is as far as I have come to understanding. Please do correct me if I am wrong .

now to Code 😄 still new to flutter or programming.

HelloMukama commented 3 years ago

I'm facing the same issue here...

AmirMoradnejad12 commented 1 year ago

step1 : fetch this : GET https://www.mysite.com/wp-json/wc/store/cart/items step 2 : in response header you can access to the nonce and car-token. ( response.headers.get('nonce ) step 3 : POST https://www.mysite.com/wp-json/wc/store/cart/items and set nonce and car-token in this request headers.

I search many time and try many ways and finally find this way.

I hope you can use it.

voxluke commented 11 months ago

step1 : fetch this : GET https://www.mysite.com/wp-json/wc/store/cart/items step 2 : in response header you can access to the nonce and car-token. ( response.headers.get('nonce ) step 3 : POST https://www.mysite.com/wp-json/wc/store/cart/items and set nonce and car-token in this request headers.

I search many time and try many ways and finally find this way.

I hope you can use it.

Thank you, I searched a lot on the internet how we gain the nonce. But finally I know!

Deepak7009 commented 3 months ago

I m still getting {"code":"woocommerce_rest_missing_nonce","message":"Missing the X-WC-Store-API-Nonce header. This endpoint requires a valid nonce.","data":{"status":401}} error In your code we are posting a request but header section only contains Auth data which is Bearer djksajlkdjlskajdlka But server asks us to send : X-WC-Store-API-Nonce data which is created by server side. We need this nonce data. and send it to server. I tried addto mychart method with 0.9.7 but still having this issue. Note i m logging in with a pre-created user with wordpress.

How to solve this ?

SDN33 commented 1 week ago

step1 : fetch this : GET https://www.mysite.com/wp-json/wc/store/cart/items step 2 : in response header you can access to the nonce and car-token. ( response.headers.get('nonce ) step 3 : POST https://www.mysite.com/wp-json/wc/store/cart/items and set nonce and car-token in this request headers.

I search many time and try many ways and finally find this way.

I hope you can use it.

THANKS SO MUCH BOSS 🫡🫡🫡 You save my day !

SDN33 commented 1 week ago

here is the solution import { NextApiRequest, NextApiResponse } from 'next'; import { wcApi } from './wcApi'; // Assurez-vous que wcApi est correctement configuré pour interagir avec WooCommerce

// Fonction pour afficher le panier export const viewCart = async () => { const response = await fetch('/api/cart', { method: 'GET', }); if (!response.ok) { throw new Error('Failed to fetch cart'); } return response.json(); };

// Handler pour gérer les requêtes API export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { method } = req; console.log(Request method: ${method}); // Log du type de requête

switch (method) { case 'GET': try { console.log('Tentative de récupération du panier...'); const cartData = await wcApi.get('cart'); console.log('Panier récupéré avec succès:', cartData.data); return res.status(200).json(cartData.data); } catch (error) { console.error('Erreur lors de la récupération du panier:', error); return res.status(500).json({ message: 'Erreur lors de la récupération du panier' }); }

case 'POST':
  try {
    const { product_id, quantity = 1, variation_id = 0, variation = {}, cart_item_data = {} } = req.body;

    // Récupérer le nonce et le cart-token
    console.log('Tentative de récupération du nonce et du cart-token...');
    const response = await fetch(`${process.env.WC_API_URL}/cart/items`);
    if (!response.ok) {
      throw new Error('Erreur lors de la récupération du nonce');
    }
    const nonce = response.headers.get('nonce');
    const cartToken = response.headers.get('cart-token');
    console.log('Nonce récupéré:', nonce);
    console.log('Cart-Token récupéré:', cartToken);

    // Validation des IDs
    const productId = absint(product_id);
    const variationId = absint(variation_id);
    console.log(`ID produit: ${productId}, ID variation: ${variationId}, Quantité: ${quantity}`);

    // Récupérer le produit
    const productData = await wcApi.get(`products/${productId}`);
    if (!productData) {
      throw new Error('Le produit spécifié n\'existe pas.');
    }

    // Vérifier la quantité
    if (quantity <= 0) {
      throw new Error('La quantité doit être supérieure à zéro.');
    }

    // Gestion des variations
    if (variationId) {
      const variationData = await wcApi.get(`products/${productId}/variations/${variationId}`);
      if (!variationData) {
        throw new Error('La variation spécifiée n\'existe pas.');
      }
    }

    // Ajouter l'article au panier
    console.log('Tentative d\'ajout de l\'article au panier...');
    const cartItemData = await wcApi.post('cart/add-item', {
      product_id: productId,
      quantity,
      variation_id: variationId,
      variation,
      cart_item_data,
    }, {
      headers: {
        'Nonce': nonce,
        'Cart-Token': cartToken,
      },
    });

    console.log('Article ajouté au panier avec succès:', cartItemData.data);
    res.status(200).json(cartItemData.data); // Retourner les données mises à jour du panier
  } catch (error) {
    console.error('Erreur lors de l\'ajout au panier:', error);
    const errorMessage = (error instanceof Error) ? error.message : 'Erreur inconnue lors de l\'ajout au panier.';
    res.status(500).json({ message: errorMessage });
  }
  break;

default:
  res.setHeader('Allow', ['GET', 'POST']);
  res.status(405).end(`Method ${method} Not Allowed`);
  break;

} }

// Fonction utilitaire pour convertir en entier function absint(value: any) { return Math.abs(parseInt(value, 10)) || 0; }