npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

shopify-session-tokens-nextjs

v0.2.0-beta.7

Published

First, set your Shopify App's public & private keys in `.env.local`

Downloads

3

Readme

This is an example Next.js project consuming Shopify App Bridge Session Tokens for authentication using utilities from shopify-nextjs-toolbox

Getting Started

First, set your Shopify App's public & private keys in .env.local

SHOPIFY_API_PUBLIC_KEY='your public api key from the Shopify app dashboard here'
SHOPIFY_API_PRIVATE_KEY='your private api key from the Shopify app dashboard here'
NEXT_PUBLIC_SHOPIFY_API_PUBLIC_KEY='same value as SHOPIFY_API_PUBLIC_KEY, this will expose your public key to the frontend'
SHOPIFY_AUTH_CALLBACK_URL='<your-sub-domain>.ngrok.io/api/auth/callback'
SHOPIFY_AUTH_SCOPES='read_customers,write_customers' # a comma separated list of Shopify Auth scopes your app requires to function
HOME_PATH = '/home' # or wherever you'd like the user to be sent to after successfully authenticating

Then make sure your app is configured to use <your-sub-domain>.ngrok.io as the entry point.

Second, start up ngrok and configure it to use localhost:3000.

Then, run the development server:

npm run dev
# or
yarn dev

How it works

This example app is using a set of utilities from the shopify-nextjs-toolbox to handle Shopify's OAuth handshake and cookie-less session token generation & verification.

OAuth Handshake

When a customer opens your app, they will be directed to your app's defined homepage in your Shopify App settings.

In _app.js use the ShopifyAppBridgeProvider component to check for authentication, and begin the OAuth process if a customer isn't logged in:

// pages/_app.js

function MyApp({ Component, pageProps }) {
  // The ShopifyAppBridgeProvider abstracts starting the OAuth process
  //   it will automatically redirect unauthenticated users to your `/api/auth.js` route
  return (
    <ShopifyAppBridgeProvider Component={Component} pageProps={pageProps}>
      <AppProvider i18n={enTranslations}>
        <Component {...pageProps} />
      </AppProvider>
    </ShopifyAppBridgeProvider>
  );
}

The OAuth flow begins at /api/auth.js. It will redirect to Shopify's authorization page. No need to do anything else besides export the built in middleware:

// pages/api/auth.js

import { handleAuthStart } from "shopify-nextjs-toolbox";

export default handleAuthStart;

After the user accepts your app's scopes and terms, they will be redirected from Shopify to /api/auth/callback.js.

That route will then verify the signature of the request and retrieve the merchant's Shopify access token.

The afterAuth function is called after the access token is successfully retrieved. Create your own afterAuth to store the shop's access token which is passed as the third argument sessionToken:

// pages/api/auth/callback.js
import { handleAuthCallback } from "shopify-nextjs-toolbox";

const afterAuth = async (req, res, accessToken) => {
  // save accessToken with the shop
  db.collection("shop").insertOne({ name: req.query.shop, accessToken });

  // redirect is handled by handleAuthCallback, no need to res.send() or res.redirect() here.
};

export default handleAuthCallback(afterAuth);

Now that the merchant's OAuth handshake is complete, the customer is finally redirected to /pages/home.js, or whichever path you provide in process.env.HOME_PATH. This route is an internal route. Meaning, it can assume that the Shopify AppBridge has a valid shopDomain query parameter, and the merchant is authenticated by OAuth.

App Bridge Session Token Retrieval

After the handshake is complete, in the _app.js the App Bridge is instantiated and the session token is retrieved. The host is transferred to your app by Shopify through the query param host={host}.

The pages/home.js is not rendered until the session token is available for consumption.

Once the page loads, then an HTTP request with the session token is sent to /api/verify-token.js where it's decoded and validated with your app's private key.

TODO

  • Implement a client side redirecting scheme to detect unauthorized use and return the user back to the oauth flow.
    • For example: https://github.com/Shopify/koa-shopify-auth/blob/master/src/auth/redirection-page.ts

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!