Password Protect Advice

Hi! Using the new Kirby 3, what is the simplest way to password-protect a page?

I’ve been reading here and there, but all info looks outdated regarding the new Kirby 3. And i can’t find any official cookbook/guide. The protection level doesn’t need to be high. Just to be simple to use; submit pass and voilá. Something simple in PHP?

Side note: I’ve read online about the Javascript solution. It looks OK, i guess, in terms of ease of use, but i don’t want any potential customer, with web development superpowers, to crack the password location and laugh at my expense :stuck_out_tongue:

Thank you in advance!

1 Like

???

There is a cookbook recipe for K2 which you could adapt for Kirby 3, we haven’t managed to update that yet.

This only protects a page/pages, but not assets. If you also need to protect files from being accessed, you would have to set up anassets firewall

1 Like

Oh, sweet! I didn’t know you could access Kirby 2 docs. BTW, i noticed most of the forum’s posts have broken links too, so now i get they probably direct to these old docs.

Looks easy, just by reading it. I’ll try it out later at the end of the day. Thanks!

Let me know how it worked out for you.

I followed the authentication process of K2. It is not working, at this moment, but i’m also not sure how to track where it is wrong. Here are some things i did/noticed.

Logging out
I didn’t change the code except where i’m defining the route. Since i’ve learned the new syntax, i believe it should be like this:

'routes' => [
    [
        // another route
    ],
    [
        'pattern' => 'logout',
        'action'  => function () {
            if($user = site()->user()) $user->logout();
            go('login');
        }
    ]
]

The log out URL doesn’t seem to work… At least, i’m still logged in in Panel.

Protecting the page
I can’t protect the page with this code, it just lets me in, even logged out of Panel:

<?php if(!$site->user()) go('/') ?>

Logging in
The log in page doesn’t seem to work too. I don’t have any way to detect it too. I can’t get the form errors and i’m not able to test if it works since the blocked page is unblocked. I’m using this code in the controller:

<?php
return function($site, $pages, $page) {
    if(r::is('post') and get('login')) {
        if($user = $site->user(get('username')) and $user->login(get('password'))) {
            go('/');
        } else {
            $error = true;
        }
   } else {
        $error = false;
   }
    return array('error' => $error);
};

Apart from this, the form looks OK, i have username, password and login names in the page.

Any ideas on how to check what is not working for sure?

Without having a closer look at this time of night, notice that it is no longer $site->user() but $kirby->user().

Protecting page:

<?php if(!$kirby->user()) go('/') ?>

Login controllers:

<?php
return function($kirby) {
  if($kirby->user()) go('/');
  if($kirby->request()->is('POST') and get('login')) {
    if($user = $kirby->user(get('email')) and $user->login(get('password'))) {
      go('/');
    } else {
      $error = 'Invalid username or password';
    }
  } else {
    $error = false;
  }

  return compact('error');
};

And Routes:

  'routes' => [
    [
      'pattern' => 'logout',
      'action'  => function() {
        $kirby   = kirby();
        if($user = $kirby->user()) {
          $user->logout();
        }
        go('login');
      }
    ],
  ]

Thanks for your help! I’m starting to see a light at the end of the tunnel, but it’s still not working.

Page protection + Log out URL
This part seems to be working by forcing a login on panel.

  1. Logged out, i enter the protected page and i’m directed to the log in page
  2. Go to panel URL to post a log in
  3. Logged in, i enter the protected page and i’m able to view it

Log in controller
I think there’s still an error here, because the log in page is not working. Attempts to post, but there is no response or redirect. Any ideas? I’m searching the reference but i’m not understanding if the line of the request is well structured.

<?php
return function($kirby) {
    if($kirby->user()) go('/');
    if($kirby->request()->is('post') and get('login')) {
        if($user = $kirby->user(get('email')) and $user->login(get('password'))) {
            go('/');
        } else {
            $error = 'testingasdasda sasd asd';
        }
    } else {
        $error = false;
    }
    return compact('error');
};

Form structure

<form method="post">
    <?php if($error): ?>
        <p><?= $page->alert_wrong() ?></p>
    <?php endif ?>
    <p>
        <label for="email">
            <small><?= $page->email_label() ?></small>
        </label>
        <br>
        <input type="email" name="email" id="email">
    </p>
    <p>
        <label for="password">
            <small><?= $page->password_label() ?></small>
        </label>
        <br>
        <input type="password" name="password" id="password">
    </p>
    <p>
        <button type="submit" name="login"><?= $page->submit_label() ?></button>
    </p>
</form>

Do not forget to add : value="login"

<button type="submit" name="login" value="login">Login</button>

OMG, i’m such a noob! Thank you @starckio, the page protection is working perfectly!

1 Like

I’m currently trying to set up a password protected section for the site I’m working on, this thread has been a great help!

What’s bugging me is that when I enter a wrong password, I don’t get the error message as html above the form element, which I thought would happen through the <?php if ($error): ?> part of the code, but instead kirby opens the debug console which states “Invalid login”.
Is there any way to prevent this and instead i.e echo the message in an alert?

I’ve added a hard-coded mail address into my controller so the user would only have to enter their password on the login page, which is working fine:

<form method="post">
<?php if($error): ?>
    <p>error</p>
<?php endif ?>
<p>Please enter the password below to continue:</p>
<p>
    <label for="password">
        Password
    </label>
    <br>
    <input type="password" name="password" id="password">
</p>
<p>
  <button type="submit" name="login" value="login">OK</button>
</p>

––

<?php
return function($kirby) {
    if($kirby->user()) go('/');
    if($kirby->request()->is('post') and get('login')) {
        if($user = $kirby->user('access@test.test') and $user->login(get('password'))) {
            go('/');
        } else {
            $error = 'Invalid Password';
        }
    } else {
        $error = false;
    }
    return compact('error');
};

also, could somebody point me in the right direction of storing the last visited page before the login redirect happens, so the user gets sent back to that page instead of the homepage?

Thanks in advance!

You might want to check out our cookbook recipe: Restricting access to your site | Kirby CMS

As regards redirecting:

Thank you for the hint! I somehow missed the cookbook recipe.