# Remember requested path in session via controller

**URL:** <https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382>\
**Category:** Questions\
**Tags:** v3\
**Created:** [January 4, 2022, 11:15pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382 "2022-01-04T23:15:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 4, 2022, 11:15pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/1 "2022-01-04T23:15:38Z")

</div>

I’m trying to create a private website, where visitors need to have a login to be able to see the content. I want to reuse the Kirby Panel login page for that.

I’ve created a default controller `site/controllers/site.php`, where I want to check whether the user is logged in or not. If he is not, I want to redirect him to the login page. But after a successful login I want to redirect him back to the initially requested page (this functionality is alread implemented by default in `src/Panel/Home.php`). So I need to set the `panel.path` property in the session.

```auto
<?php

return function ($kirby) {
  $error = false;

  if (!$kirby->user())
  {
    $intendedPath = $kirby->route()->arguments()[0] ?? null;
    $kirby->session()->set('panel.path', $intendedPath);
    go('panel');
  }

  return [
    'error' => $error,
  ];
};

```

However, the default controller is called on EVERY browser request. So in my session the `panel.path` value is always being set to `favicon.ico`, because apparently this is the last request coming from my browser.

Any idea how to “filter” the requests, so I only write to the session, when the request was for a page, and not for single files?

---

<div class="post-metadata">

**Author:** ![sebastiangreger](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sebastiangreger/32/16176_2.png) [@sebastiangreger](https://forum.getkirby.com/u/sebastiangreger)\
**Post date:** [January 5, 2022, 7:33am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/2 "2022-01-05T07:33:09Z")

</div>

At the risk of stating the obvious: wouldn’t it be possible to check with an if clause whether the returned path is a page (e.g. checking for file names in the path with a `\.(.*{3,4})$` pattern)?

That said, I had difficulties replicating your issue. The above controller only triggers once for the page in my test setup. Interestingly, for some pages it does not trigger at all; need to figure out what that’s about.

`$kirby->route()->arguments()[0]` led to a “Undefined offset” error on the home page, so maybe `$kirby->request()->path()->toString()` could be an alternative there?

PS: Closely following your work on this, @pReya – impressive PRs on the Panel bugs; looking forward to get this use case working 🥳

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 5, 2022, 8:10am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/3 "2022-01-05T08:10:28Z")

</div>

Yes, a regex would probably be possible, but I’d like to see if there are any other/more elegant solutions before I try this.

Does your test setup use a favicon? What webserver? Maybe your server config handles this differently. I’m working on a local Laravel Valet setup without a favicon.

The undefined offset error for the home page is weird. There is a null coalescing operator there, so it should always use null. It works for me.

I guess a related question from this experience is: Is the global/default site controller really supposed to be called on every request, even if the request is for files? Shouldn’t it automatically, by default only run for “page” requests?

Happy to know that somebody might want to use this stuff, too. Will create a cookbook article once this is all working as expected.

---

<div class="post-metadata">

**Author:** ![sebastiangreger](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sebastiangreger/32/16176_2.png) [@sebastiangreger](https://forum.getkirby.com/u/sebastiangreger)\
**Post date:** [January 5, 2022, 8:17am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/4 "2022-01-05T08:17:41Z")

</div>

> [@pReya](#):
>
> Yes, a regex would probably be possible, but I’d like to see if there are any other/more elegant solutions before I try this.

That’s what I thought, hence the “stating the obvious” disclaimer…

> [@pReya](#):
>
> Does your test setup use a favicon? What webserver? Maybe your server config handles this differently. I’m working on a local Laravel Valet setup without a favicon.

Valet Linux on Nginx, with Favicon set up. Maybe the `favicon.ico` request only occurs if no favicon is configured? So the fact that the global site controller (something I haven’t really worked with before, so my experience is limited) is triggered might have to do with a fallback for non-existing file URIs?

> [@pReya](#):
>
> The undefined offset error for the home page is weird. There is a null coalescing operator there, so it should always use null. It works for me.

You are of course right; sorry 'bout that – I had modified the code to run some alternative tests and the null coalescing operator got lost. User error 🙂

---

<div class="post-metadata">

**Author:** ![sebastiangreger](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sebastiangreger/32/16176_2.png) [@sebastiangreger](https://forum.getkirby.com/u/sebastiangreger)\
**Post date:** [January 5, 2022, 10:30am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/5 "2022-01-05T10:30:54Z")

</div>

> [@pReya](#):
>
> I guess a related question from this experience is: Is the global/default site controller really supposed to be called on every request, even if the request is for files? Shouldn’t it automatically, by default only run for “page” requests?

I did some more experiments (and read up properly on global controllers) and I believe the reason you are seeing the Favicon path is because the error page is triggered (which is then dealt with via the router).

Here are some potential ideas for a more elegant solution than a regex:

- `$kirby->response()->code()` returns 200 for valid requests; would solve the Favicon issue (I tried; it returns 404 when an error page is called, as can be expected), but might still return 200 for some odd URLs?
- `$page->intendedTemplate()->name()` returns `special` for the error page in my setup; checking for that could allow to rule out or only allow certain templates

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 6, 2022, 6:18pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/6 "2022-01-06T18:18:20Z")

</div>

Thank you very much for giving me a lot of good ideas.

> [@sebastiangreger](#):
>
> I did some more experiments (and read up properly on global controllers) and I believe the reason you are seeing the Favicon path is because the error page is triggered (which is then dealt with via the router).

Your suggestion about the error page is partially correct. However it is actually the other way round: The favicon is being requested first, the default controller is being called, and then the error page is returned.

So I would still be interested in anyone from the team commenting on this: Is it intended, that the default controller is being called on every request (including files like favicon)?

> [@sebastiangreger](#):
>
> `$kirby->response()->code()` returns 200 for valid requests; would solve the Favicon issue (I tried; it returns 404 when an error page is called, as can be expected), but might still return 200 for some odd URLs?

Are you absolutely sure that `$kirby->response()->code()` returns 200 for you? Because I have tested it, and it seems there is a bug in it. For me it never returns 200 (404 works correctly though). I’ve created a new bug ticket for this: [response()-\>code() does not return 200 as expected · Issue #4082 · getkirby/kirby · GitHub](https://github.com/getkirby/kirby/issues/4082)

> [@sebastiangreger](#):
>
> `$page->intendedTemplate()->name()` returns `special` for the error page in my setup; checking for that could allow to rule out or only allow certain templates

`$page->intendedTemplate()->name()` is a good idea. Thank you for this idea, I did not know about this. Will try to make it work with this function for now.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 6, 2022, 11:16pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/7 "2022-01-06T23:16:33Z")

</div>

This seems weird. The controller should only be called on pages and only if there is no specific page controller and I can’t find evidence in the code that it might be called anywhere else.

If that should indeed be the case, that would be a bug.

How did you test when the controller is called?

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 6, 2022, 11:26pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/8 "2022-01-06T23:26:33Z")

</div>

Seems I was wrong about this. It is indeed the error page that calls the default controller. Sorry, my mistake.

---

<div class="post-metadata">

**Author:** ![sebastiangreger](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sebastiangreger/32/16176_2.png) [@sebastiangreger](https://forum.getkirby.com/u/sebastiangreger)\
**Post date:** [January 7, 2022, 5:34am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/9 "2022-01-07T05:34:06Z")

</div>

> [@pReya](#):
>
> Are you absolutely sure that `$kirby->response()->code()` returns 200 for you?

I am absolutely sure I simply _deduced_ it has to be 200 for an existing page as I got a 404 for a non-existing URL 🙈 So you are right, I do not get a 200 here, sorry for the confusion.

I commented on the Github ticket, as I believe this is actually correct behaviour as Kirby has likely not assembled a Response object by the time a default controller is invoked for an existing page.

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 8, 2022, 10:05pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/10 "2022-01-08T22:05:07Z")

</div>

Sorry @texnixe (or @sebastiangreger), I know this is slightly off-topic, but also somehow connected to the remembered path in the session. I have to continue with this favicon topic for a little bit 😃 I thought I understood the logic, but it turns out I don’t. Can you explain the following behavior to me?

1. New Plainkit project
2. Create a new content page via Panel (it will use template `default`)
3. Create a new controller in `site/controllers/default.php` (not to be confused with `site.php` – this is a regular per-template controller we’re creating) and add some output via `echo`, e.g.

```php
<?php
return function () {
  echo("DEFAULT CONTROLLER");
  return true;
};

```

1. Open your newly created content page → You should see “DEFAULT CONTROLLER” in your browser, as expected
2. Open `mydomain.com/favicon.ico` in your browser (it doesn’t exist) → You will see the error page, but you will also see “DEFAULT CONTROLLER” above your content. Why is the `default` controller even being called? The error page does not use the `default` template.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 8, 2022, 10:52pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/11 "2022-01-08T22:52:44Z")

</div>

Unless you created a special template for the error page, it will use the default controller (as will any other page that doesn’t have a specific template). So what happens is the expected behavior.

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 8, 2022, 10:58pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/12 "2022-01-08T22:58:06Z")

</div>

So the `default` controller/template is special? I thought there was only one special case of controller/template name, which is the `site.php` controller.

So the order of precedence for controllers would be:

1. Is there an exact match for the template name? E.g. `myPage`
2. If no: Is there a `default`?
3. If no: Is there a `site`?

EDIT: It gets clearer looking at the [documentation for templates](https://getkirby.com/docs/guide/templates/basics#the-default-template). Unfortunately the [docs for controllers](https://getkirby.com/docs/guide/templates/controllers#creating-a-controller) are a little misleading. Under the headline “Default controller” you will find the `site` controller, but the `default` controller is never mentioned.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 8, 2022, 11:06pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/13 "2022-01-08T23:06:09Z")

</div>

The default.php controller is only used for the default.php template. The connection between content file, template and controller is always by filename and the default.php template is just a fallback.

The only exception from the naming scheme is the site.php controller. If it exists and there is no specific controller for a template, the site.php controller is used.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 8, 2022, 11:09pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/14 "2022-01-08T23:09:23Z")

</div>

> [@pReya](#):
>
> Under the headline “Default controller” you will find the `site` controller,

Yes, the naming there is a bit unfortunate. Maybe we should call it “general controller” to avoid confusion?

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 11, 2022, 11:35pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/15 "2022-01-11T23:35:06Z")

</div>

So, after a lot of confusion, I’m back to my original plan (using the Kirby login page as a login for Frontend users – users who have no panel access), including redirecting them back to their original requested location after the login. I’ve stopped using both the default and or the “site” controller for doing this. Instead, here is my “protected” controller:

```php
<?php

use Kirby\Cms\Url;

return function ($kirby) {
    $error = false;

    if (!$kirby->user()) {
        $intendedPath = $kirby->route()->arguments()[0] ?? null;

        if (isset($intendedPath)) {
            // This needs to be an absolute URL, a relative path to a frontend
            // page will not work (b/c the panel will always add '/panel/' to
            // the path)
            $intendedPath = Url::to($intendedPath);
            $kirby->session()->set('panel.path', $intendedPath);
            $error = true;
            go('panel/login');
        }
    }

    return [
        'error' => $error,
    ];
};

```

However for some reason, the `panel.path` in the Session will always be overridden by another value. I’ve found out, that somehow the `login.fallback` route in `kirby/config/areas/login.php` will always mess up my path in the session. If I uncomment this route, everything works like a charm.

```php
<?php

use Kirby\Panel\Panel;

return function ($kirby) {
    return [
        'icon' => 'user',
        'label' => t('login'),
        'views' => [
            'login' => [
                'pattern' => 'login',
                'auth' => false,
                'action' => function () use ($kirby) {
                    $system = $kirby->system();
                    $status = $kirby->auth()->status();
                    return [
                        'component' => 'k-login-view',
                        'props' => [
                            'methods' => array_keys($system->loginMethods()),
                            'pending' => [
                                'email' => $status->email(),
                                'challenge' => $status->challenge()
                            ]
                        ],
                    ];
                }
            ],
            // Uncommenting this block makes my controller work
            // 'login.fallback' => [
            // 'pattern' => '(:all)',
            // 'auth' => false,
            // 'action' => function ($path) use ($kirby) {
            // /**
            // * Store the current path in the session
            // * Once the user is logged in, the path will
            // * be used to redirect to that view again
            // */
            // $kirby->session()->set('panel.path', $path);
            // Panel::go('login');
            // }
            // ]
        ]
    ];
};

```

Any ideas what happens here? Can anyone explain to me, what this `login.fallback` route is doing?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 12, 2022, 8:32am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/16 "2022-01-12T08:32:50Z")

</div>

> When a user logs in to the Panel, they normally get redirected to the last view they were on before they were logged out,

I’d say the login.fallback is responsible for that.

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 12, 2022, 3:28pm UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/17 "2022-01-12T15:28:09Z")

</div>

@distantnative Do you maybe have any idea, how to allow frontend pages as redirect targets in the `panel.path` session value, so it doesn’t collide with the `login.fallback` route?

---

<div class="post-metadata">

**Author:** ![sebastiangreger](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sebastiangreger/32/16176_2.png) [@sebastiangreger](https://forum.getkirby.com/u/sebastiangreger)\
**Post date:** [January 14, 2022, 9:19am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/18 "2022-01-14T09:19:34Z")

</div>

I just gave this a try on the `develop` branch with the upcoming changes for 3.6.2 and it worked flawlessly. Here’s what I did; maybe this helps tracking down where your approach runs into that error?

1 – Created a route for `login/(:all)`, but that’s of course just one of many ways to set the logintarget in the session:

```auto
// in config.php -> routes
[
    'pattern' => 'login/(:all)',
    'action' => function ($path = null) {
        kirby()->session()->set('myplugin.logintarget', $path);
        go('panel/login');
    }
],

```

2 – Created a user blueprint for the role I am targeting (for testing purposes, I simply used `admin.yml` temporarily):

```auto
# admin.yml
home: "{{ site.logintarget }}"
permissions:
  access:
    panel: false

```

3 – Created a plugin providing the site method `logintarget`:

```auto
// site/plugins/myplugin/index.php
Kirby::plugin('myplugin/logintarget', [
    'siteMethods' => [
        'logintarget' => function () {
            $target = kirby()->session()->pull('myplugin.logintarget');
            if ($target === null) {
                return '/panel';
            }
            return $target;
        }
    ]
]);

```

Now when I go to `https://example.com/login/blog`, I get forwarded to the login form and after entering my credentials end up on the `https://example.com/blog` page, now logged in as a user. If I go directly to the login form without a pre-existing session, I get forwarded to `https://example.com` as I’d expect (since access to the panel is forbidden and no logintarget stored in the session).

This is where I originally ended up with the two bugs that have now been fixed. What context am I missing to reproduce the error you described?

---

<div class="post-metadata">

**Author:** ![pReya](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/preya/32/8757_2.png) [@pReya](https://forum.getkirby.com/u/pReya)\
**Post date:** [January 14, 2022, 9:26am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/19 "2022-01-14T09:26:51Z")

</div>

@sebastiangreger Wow! Thanks so much for this input! It is a different approach to mine. I tried to “reuse” the existing `panel.path` in the session, which Kirby automatically uses to redirect to.

But now that I see your approach, using your own session value via plugin in combination with the (now fixed) `home:` property of the user blueprint makes much more sense.

I will implement this over the weekend, and see if I still discover any problems with it. But this is looking extremely good. Thanks so much for your input!

---

<div class="post-metadata">

**Author:** ![sebastiangreger](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/sebastiangreger/32/16176_2.png) [@sebastiangreger](https://forum.getkirby.com/u/sebastiangreger)\
**Post date:** [January 14, 2022, 10:42am UTC](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382/20 "2022-01-14T10:42:38Z")

</div>

👍

Please note I edited the plugin code in my example above after some more experimentation – we have to check for the result of the session pull. While `home: null` in a user blueprint works just fine to send the user to the panel, it does for some reason not work when the page method returns `null` …I kept ending up on the frontend root URL instead.

…only applies to users with panel access, of course. Otherwise the default behaviour is probably fine.

[Next page](https://forum.getkirby.com/t/remember-requested-path-in-session-via-controller/24382.md?page=2)
