Skip to content

Instantly share code, notes, and snippets.

@jasonvarga
Created September 23, 2016 16:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasonvarga/3af8d44e2037eb0c1357a0a6e8310749 to your computer and use it in GitHub Desktop.
Save jasonvarga/3af8d44e2037eb0c1357a0a6e8310749 to your computer and use it in GitHub Desktop.
Statamic 2 Content Protection

Protecting Content {#protecting-content}

You may protect your content from unwanted visitors with the protect variable. By setting this variable you can allow or deny people in various ways. There are a number of schemes used for protecting content:

The protect variable can be placed in a number of places:

  • In content (pages, entries, and taxonomy terms.)
  • In folder.yaml files, which would cascade down and protect all entries, terms, child pages.
  • Directly into routes.

To protect content, you should add a protect array, like so:

title: My Protected Content
protect:
  password:
    allowed: ['secret']

This example uses the password scheme, but you should simply place whatever scheme you require in there. They're all documented below.

Whichever scheme choose, know that protect is designed to help you out. We’ve tried to keep the syntax as simple as possible to use while at the same time allowing for a lot of flexibility. Because of this, if Statamic sees that protect has been set but it isn’t able to parse the requirements you’ve set, all users will always be denied. In these instances, a message will be written to the log telling you that something’s gone wrong.

Configuring {#configuring-protection}

There are some aspects to content protection that you may like to apply across your site. The following settings can be added to site/settings/system.yaml:

  • protect_password_form_url is where a user will be redirected when a password scheme is set but the user has not yet entered in a valid password.

Password protection {#password-protection}

There will be times when you want to password-protect one or more files, but don’t want to bother with having people create member accounts just to access a page. That is where using the password scheme comes in. This scheme does not relate to user accounts in any way, only one-off password entry. The setup for this would look something like the following:

protect:
  password:
    allowed: [ "my-password", "another-password" ]
    form_url: /password-entry

This tells Statamic to protect this content file with a password. You provide one or more valid allowed passwords (case-sensitive), and that it should forward people that haven’t entered the correct password to form_url (either another page or route you've set up).

Note: the form_url variable is optional here, if you don’t include it, protect will use the URL configured in protect_password_form_url in system.yaml

Password Form

Next, you’ll need to provide a way for people to enter passwords for URLs. In the above example, form_url is pointing to /password-entry, but this can be anywhere on your site. The easiest way is to point a route at a template:

routes:
  /password-entry: password-entry
{{ protect:password_form }}
    {{ if no_token }}
        <p>No token has been provided.</p>
    {{ else }}
        {{ if error }}
            <p class="error">{{ error }}</p>
        {{ /if }}

        Password:
        <input type="password" name="password" />

        <button type="submit">Submit</button>
    {{ /if }}
{{ /protect:password_form }}

The protect:password_form tag is going to wrap everything between the tags in an HTML form tag that’s pointing to the appropriate place. Note that the HTML of the form itself is up to you. The only requirements of this form are that the user is entering passwords into a field named password. Other than that you can do anything you’d like.

A token will be added to the URL when redirected from the protected page. If you visit the password page without a token, no_token will be true, and you can output a message if you like.

Invalid Passwords

If someone submits a password and it isn’t valid, Statamic will redirect the user back to the form, populating the error tag with an error message. In the example above, you can see that we’re printing it out if it’s there. Valid passwords can vary from piece of content to piece of content. This one form is smart enough to handle all password management between password-protected URLs.

Valid Passwords

A valid password is one that matches any of the passwords in the allowed list as configured on the page. This means that you can send three people three different passwords to access the same file, each having their own way in. Additionally, you could also set just one password and send that to 100 people and they can all use the same password.

It should go without saying, but for the sake of completeness here be careful in how you set and give out passwords.

Password Expiration

Each user’s passwords will expire once their session has expired. To manually invalidate a password, simply remove it from the list of allowed passwords on the page. The next time a user with that password visits this page, they’ll be redirected to the password form just like everyone else.

IP Address Protection {#ip-address-protection}

This scheme is super simple in that people will either be allowed in or not. The setup looks like this, similar to password:

protect:
  ip_address:
    allowed: [ 127.0.0.1 ]

We set the scheme to be ip_address, and create a list of allowed IP addresses. If the visitor’s IP address matches one of the IP addresses in this list, they will be allowed in, otherwise, they will be shown the access denied template.

Site-wide Protection {#sitewide-protection}

Instead of just applying protection to content one by one, it's possible to protect your whole site. This could be useful if you'd like show the site to your client but don't want anyone else to see, for example. You can even pair this with environment specific settings for added flexibility.

To do this, simply add a protect scheme to your site/settings/system.yaml file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment