Skip to content

Instantly share code, notes, and snippets.

@remy

remy/auth-with-cookies.md Secret

Last active Apr 5, 2020
Embed
What would you like to do?

Add the following in ./pages/login.js just before we redirect the user with router.push('/');

const { token } = json;
const cookie = require('js-cookie');
cookie.set('token', token);

And replace ./lib/withUser.js with:

import React from 'react';
import fetch from 'isomorphic-unfetch';

const API = process.env.API;
const isServer = typeof window === 'undefined';

function getToken({ req, token }) {
  if (token) {
    return token;
  }

  // get the token somehow…
}

async function getUser(token) {
  if (!token) {
    return null;
  }

  // if we remain on the client side, let's cache to speed things up
  if (!isServer) {
    if (window.__user) {
      return window.__user;
    }
  }

  const res = await fetch(`${API}/user`, {
    credentials: 'include',
    mode: 'cors',
    headers: {
      authorization: `bearer ${token}`,
    },
  });

  if (res.status === 200) {
    const user = await res.json();
    if (!isServer) {
      window.__user = user;
    }
    return user;
  }

  return null;
}

export const appWithUser = App => {
  return class AppWithUser extends React.Component {
    static async getInitialProps(appContext) {
      const token = getToken(appContext.ctx);
      const user = await getUser(token);

      appContext.ctx.user = user;
      appContext.ctx.token = token;

      let appProps = {};
      if (typeof App.getInitialProps === 'function') {
        appProps = await App.getInitialProps.call(App, appContext);
      }

      return {
        ...appProps,
      };
    }

    render() {
      return <App {...this.props} />;
    }
  };
};

export default Component => {
  return class extends React.Component {
    static async getInitialProps(ctx) {
      let props = {};

      const token = getToken(ctx);
      const user = await getUser(token);

      if (typeof Component.getInitialProps === 'function') {
        props = await Component.getInitialProps(ctx);
      }

      return { ...props, user, token };
    }

    render() {
      return <Component {...this.props} />;
    }
  };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.