简体   繁体   中英

Next JS express jwt authentication

I've implemented a /api/login to login a user. I also have a page login.js , that sends the form data to the login API. My login api checks the user credentials in my database and then signs a token and saves it to a cookie. My /api/login :

await authCollection.findOne(
  {
    authCode: req.body.authcode,
  },
  function(err, doc) {
    if (err) throw err;
    if (!doc) return res.status(400).send('auth not found');
    if (doc) {
      const token = jwt.sign({ _id: doc._id }, process.env.TOKEN_SECRET);
      res
        .status(200)
        .cookie('token', token, {
          maxAge: 2 * 60 * 60 * 1000,
          httpOnly: false,
        })
        .send(token);
    }
  },
);

I can protect my api routes with passing in a middleware like this:

function(req, res, next) {
  const token = req.cookies.token || '';
  if (!token) {
    return res.status(401).send('Access denied');
  }

  try {
    const decrypt = jwt.verify(token, process.env.TOKEN_SECRET);
    req.user = {
      id: decrypt.id,
      firstname: decrypt._id,
    };
    next();
  } catch (err) {
    res.status(400).send('Invalid token');
  }
}

I do not understand how I can protect normal pages, which are in my /pages directory. Could somebody give me a hint in the right direction? I have already googled and read each page, but couldn't implement

It depends, what I've done is to write an hoc privateArea which returns new component that fetches users accessToken from the API, then decodes it, if user is logged in, renders the wrapped page, otherwise, renders "restricted area" message.

export function privateArea(PageComponent) {
  const PrivateArea = ({ accessToken, pageProps }) => {
    const user = decodeToken(accessToken);
    if (user) {
      return <PageComponent {...pageProps} />;
    } else {
      return <RestrictedArea />;
    }
  };

  PrivateArea.getInitialProps = async (...args) => {
    const accessToken = await api.getAccessToken();

    if (typeof PageComponent.getInitilProps === 'function') {
      const pageProps = await PageComponent.getInitilProps(...args);
    }
    return {
      accessToken,
      pageProps: pageProps || {},
    };
  };
  return PrivateArea;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM