Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QL Session Handler #88

Merged

Conversation

kidunot89
Copy link
Member

@kidunot89 kidunot89 commented Jun 20, 2019

Your checklist for this pull request

Thanks for sending a pull request! Please make sure you click the link above to view the contribution guidelines, then fill out the blanks below.

🚨Please review the guidelines for contributing to this repository.

  • Make sure you are making a pull request against the develop branch (left side). Also you should start your branch off our develop.
  • Make sure you are requesting to pull request from a topic/feature/bugfix branch (right side). Don't pull request from your master!

What does this implement/fix? Explain your changes.

Implements QL_Session_Handler and filters it in using the woocommerce_session_handler hook on GraphQL requests. It functions essentially the same as the core session handler with one key difference, instead of saving the session data to a cookie, it encrypts the data and saves it to a header. woocoommerce-session is the default header name but this can be alternated with a filter woocommerce_session_header_name.

In order to use the session header the valid unaltered session data must be passed as a header with the same name as the session header the data was retrieve from. Upon creation or changes to the session key, the session header is pass with the new value. When the session is destroyed, like when the user logs out, the session header is pass with the value 'false'.

It's recommend that when use the session header middleware and afterware functionality be leverage on the respective GraphQL client. See below for example of how to do with ApolloClient and the apollo-link library.

Example client-side implemention with ApolloClient

import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { ApolloLink } from 'apollo-link';

const httpLink = new HttpLink({
  uri: 'http://example.com/wordpress/graphql',
});

/**
 * Middleware operation
 * If we have a session token in localStorage, add it to the GraphQL request as a Session header.
 */
export const middleware = new ApolloLink((operation, forward) => {
  /**
   * If session data exist in local storage, set value as session header.
   */
  const session = localStorage.getItem('woo-session');
  if (session) {
    operation.setContext(({ headers = {} }) => ({
      headers: {
        'woocommerce-session': `Session ${session}`,
      }
    }));
  }

  return forward(operation);
});

/**
 * Afterware operation
 * This catches the incoming session token and stores it in localStorage, for future GraphQL requests.
 */
export const afterware = new ApolloLink((operation, forward) => {
  return forward(operation).map((response) => {
    /**
     * Check for session header and update session in local storage accordingly. 
     */
    const context = operation.getContext();
    const { response: { headers } } = context;
    const session = headers.get('woocommerce-session');
    if (session) {
      if ( localStorage.getItem('woo-session') !== session ) {
        localStorage.setItem('woo-session', headers.get('woocommerce-session'));
      }
    }

    return response;
  });
});

const client = new ApolloClient({
  link: middleware.concat(afterware.concat(httpLink)),
  cache,
  clientState: {},
});

Does this close any currently open issues?

Any relevant logs, error output, GraphiQL screenshots, etc?

(If it’s long, please paste to https://ghostbin.com/ and insert the link here.)

Any other comments?

Where has this been tested?

Operating System: Ubuntu 18.04

WordPress Version: 5.2

@kidunot89 kidunot89 added enhancement work in progress labels Jun 20, 2019
@kidunot89 kidunot89 self-assigned this Jun 20, 2019
@kidunot89 kidunot89 changed the title QL_Session_Handler QL Session Handler Jun 20, 2019
@MobyDigg
Copy link

@MobyDigg MobyDigg commented Nov 30, 2020

@kidunot89 thanks for this. Is there an example with fetch() anywhere online?

@kidunot89
Copy link
Member Author

@kidunot89 kidunot89 commented Nov 30, 2020

https://woographql.com/playground

The user login buttons in the GraphiQL component use fetch. You can see them in the docs/ app.

@MobyDigg
Copy link

@MobyDigg MobyDigg commented Nov 30, 2020

image

…sorry, I can't find it @kidunot89

@kidunot89
Copy link
Member Author

@kidunot89 kidunot89 commented Nov 30, 2020

@MobyDigg My bad, I haven't updated the Docs app since the WPGraphQL v1.0. I'll get it updated ASAP. Here is the React Component that implements the playground

@kidunot89
Copy link
Member Author

@kidunot89 kidunot89 commented Nov 30, 2020

@MobyDigg The server has been updated, and the playground is working again

@muhaimincs
Copy link

@muhaimincs muhaimincs commented Dec 7, 2020

@kidunot89 any example implementation using React-Native. I thought it should be the same but I keep getting a new woo-commerce session when query or mutation. How to resolve the keep changing woo-commerce session?

@leftis
Copy link

@leftis leftis commented Mar 22, 2021

@kidunot89 Question: Does the woocommerce-session returns on specific calls? For example addToCart mutation returns it?
I was working with it but then i altered something and broke it and can't find out what. I now get

{"errors":[{"debugMessage":"Call to a member function add_to_cart() on null","message":"Internal server error","extensions":{"category":"internal"},"locations":[{"line":2,"column":5}],"path":["addToCart"]}],"data":{"addToCart":null},"extensions":{"debug":[]}}

It looks like the response on add-to-cart mutation doesnt include the woocommerce-session. Any help on it please?

@kidunot89
Copy link
Member Author

@kidunot89 kidunot89 commented Mar 22, 2021

@leftis You should get a woocommerce-session response header after addToCart, login, and registerCustomer. Also note that you can now get the session token using the following query

customer {
  sessionToken
}

@leftis
Copy link

@leftis leftis commented Mar 23, 2021

@leftis You should get a woocommerce-session response header after addToCart, login, and registerCustomer. Also note that you can now get the session token using the following query

customer {
  sessionToken
}

Don't know what I am doing wrong, it was working before upgrading on later versions but now for some reason it keeps returning

{"errors":[{"debugMessage":"Call to a member function add_to_cart() on null","message":"Internal server error","extensions":{"category":"internal"},"locations":[{"line":2,"column":5}],"path":["addToCart"]}],"data":{"addToCart":null},"extensions":{"debug":[]}}

is it a prerequisite to have the jwt plugin installed for the addToCart mutation to work?

@micmc422
Copy link

@micmc422 micmc422 commented May 17, 2021

I have the exact same issue as @leftis, i try jwt plugin, cors plugins, but not efficient.

problem solved by deleting plugins via ftp and re-installing them on wordpress server.

hope it can help you.

@gsdavris
Copy link

@gsdavris gsdavris commented May 21, 2022

@kidunot89 @imranhsayed How to implement this on server side? when the locale storage is not available; (requests from api routes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants