Gating content with JavaScript (Netlify Identity): Content flashes in slow connections, how to only load it after log in check?

Viewed 436

I am not really a web app developer and I would like to ask about best practices for gating website content.

I am preparing to deploy documentation created with mkdocs. It uses Netlify Identity because with that Github auth is available without any coding.

My current solution: I have added the Netlify Identity script in head and the login/logoff button via template addons in mkdocs, and then created a static document /login/ (that gets picked up automatically in mkdocs but does not get generated with template).

In the standard template there is a JS redirect to /login/ unless user is logged in:

if (window.netlifyIdentity) {
 window.netlifyIdentity.on("init", user => {
  if (!user) {
    document.location.href = "/login/";
  }
});
}

On the static page there is a redirect to / only just after user has logged in:

  if (window.netlifyIdentity) {
    window.netlifyIdentity.on("init", user => {
      if (!user) {
        window.netlifyIdentity.on("login", () => {
          document.location.href = "/";
        });
      }
    });
  }

I hope this is a reasonable way to go about it. The docs do not store anything critical but I still wouldn't want that content exposed.

But I have noticed on slow connection the redirect takes a second or two so when a deep URL is accessed the content flashes on the screen before login.

What can be done to stop this and load the content only after the login check is performed?

2 Answers

This is not going to work as you desire and is not secure.

If I wanted to read your content without an account, I could simply disable JavaScript in my browser (a few mouse clicks) and your site would load, but the redirect would never run.

Regardless, with JavaScript enabled, the way it works is that the browser downloads the page, then downloads any resources (including scripts), and then finally runs any scripts. There is no way to change that. Of course, on a fast system, the user may not perceive a delay, as the delay is very short, but there is always a delay. That is how browsers work.

If you don't want your users to have access to the information until after they are logged in , then you must not send the information out until they are logged in. In other words, you need to configure your server to not send the page at all until it receives verification that the user has permission to receive that information. How you do that depends on which server you are using among other things, which would be the subject of a separate question.

I know this is a old post but you can use netlify functions combined with a netlify redirect file.

You would have to set a role of a user when signing up using the metadata, you could do this with a netlify function thats hooked into netlify identity, more here.

Create a function called identity-signup.js when a user signs up this function is automatically called.

exports.handler = async (event) => {
    const { user } = JSON.parse(event.body)
    // you could do something with the user here: eg console.log(user.email)
    // or using stripe: const customer = await stripe.customers.create({ email: user.email });
    return {
        statusCode: 200,
        body: JSON.stringify({
            app_metadata: {
                roles: ['free']
            }
        })
    }
}

Once you have a role you can simply create a _redirects file like so:

/authedcontent/* 200! Role=free
/authedcontent/ / 404

Later down the line you can extend the netlify function to save the users detail in an external database or maybe setup a stripe subscription.

The only caveat is that this requires a paid netlify account.

Related