pasdo501 / gatsby-source-woocommerce

Gatsy Source Plugin for WooCommerce
34 stars 14 forks source link

Customer Auth #10

Closed PolGuixe closed 1 year ago

PolGuixe commented 5 years ago

@pasdo501 Is it possible to Authenticate (Sign Up / Sign In) users to access their private data? e.g. orders, etc.

Thanks,

pasdo501 commented 5 years ago

Hi,

You can get customer orders if you add "orders" to the fields option in gatsby-config.js, and then use a query like

{
  allWcOrders {
    nodes {
      customer_id
      customer_ip_address
      currency
      total
      wordpress_id
    }
  }
}

The actual authentication to make sure users only see their own data is probably the more difficult bit. The Gatsby authentication tutorial and Gatsby Authentication Demo may be useful to you! Putting the data on private routes may be what you're looking for? There's also a bunch of useful links at the moment of the tutorial.

Not sure if that's useful to you, but I think that's how I'd approach it.

PolGuixe commented 5 years ago

@pasdo501 many thanks for the references. I am more familiar with the GatsbyJS side of the problem.

What it is not that clear to me is have a customer could access the Wordpress/Woocommerce Auth API? And then which API to use to access customer relevant data in the eCommerce.

In this reference, they are talking about building a proxy: https://www.codeinwp.com/blog/progressive-web-apps-on-wordpress-and-woocommerce/#WooCommerce

Is there any other approach?

pasdo501 commented 5 years ago

Oh! So you're less interested in having that data available at build time, but get it dynamically later on as needed like a more standard app, is that right?

PolGuixe commented 5 years ago

Yes.

Certain user interactions:

These will be dynamic. So I am not sure if the Wordpress/Woocommerce API is prepared for this kind of interactions. What do you think?

The other approach is to have like a hybrid app:

In the scenario above I am not sure how I would transfer the info from the cart (info will be in the Gatsby site) to the Woocommerce checkout. I don't see any API to recover a checkout url, like in Shopify. Can it be done through URL parameters?

pasdo501 commented 5 years ago

Out of the box, I don't think the Wordpress API supports user Sign up / Sign in. You can read orders with the WooCommerce API, which has an npm package available (which is what this source plugin uses). However, since you need to provide it with the customer key / secret, you end up with that security issue mentioned in the reference you linked, which is why they build that proxy to keep the key / secret on the server.

Checkout, again, doesn't have an endpoint available out box as far as I know.

I think your best option is to create custom endpoints for the WordPress / WooCommerce REST API that do what you need, and then use them from your app (e.g. for the checkout endpoint see this link as an example, although that only processes the payment, and doesn't create the order). That sounds like the second approach you mention. Custom REST API endpoints can really do whatever kind of processing you need, so they're quite flexible!

On a project I worked on, I created a cart using Redux on the Gatsby / React side of things, and then used a custom endpoint on the server that took the cart information as part of the body of a POST request, did the payment processing, etc, and then returned whether it worked or there was an error. The data I sent to the server was more or less just an array of product IDs and their quantities, data from the checkout (name, address, etc), and a token created by stripe for payment processing purposes.

Hope this helps!

siemah commented 4 years ago

Hi, If you want to implement login using a wordpress with gatsby, you can user JWT Authentication for WP-API plugin for backend side (wordpress and woocommerce) and for gatsby use gatsby auth mentioned by @pasdo501 in 1st answer. When you setup JWT Authentication for WP-API plugin, maybe enable CORS if you are using subdomain, then you can send request for login to https://sub.domain.com/wp-json/jwt-auth/v1/token with user credential (email/username with password) after that handle responses maybe use redux or react context api to save user data and allow loggedin users to reach protected routes. If you want to use a woocommerce api read orders as you mentioned above then you can extend wordpress api. by adding new routes as said on wordpress doc for exemple: `

add_action( 'rest_api_init', function () {
  register_rest_route( 'dayenio/v1', '/user/(?P<id>\d+)/orders', array(
    'methods' => 'GET',
    'callback' => 'retrieve_user_orders',
  ) );
} );

function retrieve_user_orders($data) {
 $user = get_user_by('id', $data['id']);

    $query = new WC_Order_Query(['return' => 'ids',]);
    $query->set( 'customer_id', $data['id'] );
    $ordersIds = $query->get_orders(['return' => 'ids']);
    $orders = [];

    foreach($ordersIds as $orderId) {
        // return wcs_get_subscriptions_for_order($orderId);
        $order =  wc_get_order($orderId);
        $orderDetails = [];
        $orderDetails['id']  = $order->get_id(); // Get the order ID
        $orderDetails['parent_id'] = $order->get_parent_id(); // Get the parent order ID (for subscriptions…)

        $orderDetails['user_id']   = $order->get_user_id(); // Get the costumer ID
        $orderDetails['user']      = $order->get_user(); // Get the WP_User object

        $orderDetails['order_status']  = $order->get_status(); // Get the order status 
        $orderDetails['currency']      = $order->get_currency();
        $orderDetails['price']      = $order-> get_order_item_totals();
        $orderDetails['payment_method'] = $order->get_payment_method(); // Get the payment method ID
        $orderDetails['payment_title'] = $order->get_payment_method_title(); // Get the payment method title
        $orderDetails['date_created']  = $order->get_date_created(); // Get date created (WC_DateTime object)
        $orderDetails['date_modified'] = $order->get_date_modified(); // Get date modified (WC_DateTime object)
        $orders[] = $orderDetails; 
    }
    return $orders;
    // return  woocommerce->get('orders');
}

Or you can send a request to woocommerce api but its work for users who has roles of admin or shop_manager i didn't try it for users who has customer role, to do that :

fetch('https://sub.domain.com/wp-json/wp/v2/users/me', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ${token-received-from-jwt-plugin}', }, body: JSON.stringify({...details, name: '${details.fname} ${details.lname}'}), })

this code above allow to any kind of users to update their profile, this work if you send the token received from JWT Authentication for WP-API plugin as Authorization header.

Hope this what you want to do

shendriksza commented 4 years ago

We made use of the following plugin for a while to register users via REST API: https://wordpress.org/plugins/wp-rest-user/

Although I would strongly suggest you to try and write your own WordPress plugin to extend REST API functionality. It's actually not hard at all to implement, I'll be willing to help you out with some code snippets if you want