# Displaying logged-in user in header

**URL:** <https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666>\
**Category:** Need Help\
**Created:** [April 16, 2020, 9:57am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666 "2020-04-16T09:57:44Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 16, 2020, 9:57am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/1 "2020-04-16T09:57:44Z")

</div>

After completing the authentication tutorial I want to see whether and who is logged in.  
Only the following from the authentication tutorial gave me a clue where the current user is stored:

` $this->request->getAttribute('identity')->getIdentifier();`

However, this is within the ArticleController object.

How to access the identifier globally and how to echo this into the header continuously?  
From this follows the desire to have a log-out link referring to the logout() function in the UserController. How can this be accessed from “the general header” (which includes the home logo, API and Documentation)?

I quite doubt whether this basic question is not asked before, but I couldn’t find it.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 16, 2020, 2:17pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/2 "2020-04-16T14:17:38Z")

</div>

You can use `Router::getRequest()->getAttribute('identity')` anywhere in the system. Or, maybe better, have a universal `beforeRender` function in your base controller class which uses `$this->request->getAttribute('identity')` to `set` what you need as a view variable.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 18, 2020, 7:27am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/3 "2020-04-18T07:27:05Z")

</div>

Thanks . I assume ‘base controller class’ refers to AppController.php? And does that beforeRender needs the same setup as beforeFilter?  
public function beforeRender (\Cake\Event\EventInterface $event)  
{  
parent::beforeRender ($event);  
$this-\>request-\>getAttribute(‘identity’)  
}  
Echo’ing the identity doesn’t work since it is not convertible to a string. I don’t understand how to setup the view of the common header. The example of set()-\>view is in e.g. ArticlesController.php where functions/controllers refer to a specific URL view.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 18, 2020, 8:07am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/4 "2020-04-18T08:07:13Z")

</div>

From debugging I learned that the to-be-printed email is stored like this:  
object(App\Controller\ArticlesController){  
‘identity’ =\> object(Authorization\Identity) {  
[protected] attributes =\>  
[protected] identity =\> object(Authentication\Identity) {

```
				'config' => [
					'fieldMap' => [
						'id' => 'id'
					]
				], ['data' => object(App\Model\Entity\User) {

						'id' => (int) 3,
						'email' => 'x@y.nl', ...

```

So I have to access at a deeper level than identity? Which is not `echo($this->request->getAttribute('identity')->'data'->'email');` 😅

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 18, 2020, 1:51pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/5 "2020-04-18T13:51:26Z")

</div>

> [@HypJ3U50N](#):
>
> I assume ‘base controller class’ refers to AppController.php?

Correct.

> [@HypJ3U50N](#):
>
> And does that beforeRender needs the same setup as beforeFilter?

The various [request life cycle callbacks](https://book.cakephp.org/3/en/controllers.html#request-life-cycle-callbacks) are all well documented, no need to guess about this or just hope for the best.

> [@HypJ3U50N](#):
>
> I don’t understand how to setup the view of the common header. The example of set()-\>view is in e.g. ArticlesController.php where functions/controllers refer to a specific URL view.

You don’t want to set the view with this, you want to [set a variable for the view](https://book.cakephp.org/3/en/controllers.html#setting-view-variables). For example,

```
$this->set('identity', $this->request->getAttribute('identity'));

```

The variable `$identity` will now be available in any view that gets rendered by this request, including the specific view for the action being run, any elements it might call, and, most importantly for the purpose at hand, your layout.

> [@HypJ3U50N](#):
>
> `echo($this->request->getAttribute('identity')->'data'->'email');`

Documentation of [the identity object](https://book.cakephp.org/authentication/1/en/identity-object.html#the-identity-object) states that “The identity object provides ArrayAccess but as well a `get()` method to access data. It is strongly recommended to use the `get()` method over array access”, so getting the email address in a view should be as simple as `$identity->get('email')`. Do remember that `getAttribute('identity')` may return `null` if the user is not logged in, so be sure to check for that scenario, e.g. along these lines:

```
echo $identity ? $identity->get('email') : 'Not logged in';

```

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 18, 2020, 6:42pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/6 "2020-04-18T18:42:59Z")

</div>

> [@Zuluru](#):
>
> echo $identity ? $identity-\>get(‘email’) : ‘Not logged in’;

That is a clear explanation, thank you very much. I don’t understand the need for the range of event handlers, but the basic understanding is more important for now. However, the set variable is unknown in the view ( [**Notice** (8)](javascript:void(0);): Undefined variable: identity [ **APP/View\AppView.php** )

AppController.php  
public function beforeRender(\Cake\Event\EventInterface $event){  
parent::beforeRender($event);  
$this-\>set(‘identity’, $this-\>request-\>getAttribute(‘identity’));  
}

AppView.php  
public function initialize(): void  
{  
echo $identity ? $identity-\>get(‘email’) : ‘Not logged in’;  
#echo(‘a la playa’);  
}

Is this due to the difference between Event $event and the way I used it ? (which was necessary to comply with a Controller file, probably by using the initial bake all command)

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 19, 2020, 3:33am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/7 "2020-04-19T03:33:52Z")

</div>

Have you confirmed that the `beforeRender` function is actually being called? There are various scenarios which might be preventing that, and troubleshooting those is very different from troubleshooting why the `set` doesn’t appear to work.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 19, 2020, 1:17pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/8 "2020-04-19T13:17:23Z")

</div>

I thought the beforeRender to be automatically triggered. I called it explicitly in the initialize of AppController by $this-\>render(); which is obviously not the right way, based on the occurring errors.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 19, 2020, 2:55pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/9 "2020-04-19T14:55:46Z")

</div>

Yes, the `beforeRender` event should be automatically triggered and sent to your controller at the appropriate time in the request lifecycle, which is not during initialization. You should only need to create it, not call it.

The question is whether your function (which you’ve included above) is being called. There are, as I said, things that might stop that from happening. I don’t want to dive into theoretical possibilities related to that if it’s not the actual problem, though, as it only muddies the waters. So, first check whether your function is being called, yes or no, and we proceed from there.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 20, 2020, 10:55am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/10 "2020-04-20T10:55:13Z")

</div>

Based on an executed echo inside beforeRender(), it does.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 20, 2020, 4:05pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/11 "2020-04-20T16:05:19Z")

</div>

Oh, I see the problem! You’re trying to reference the `$identity` variable in a function inside `AppView`. That’s not so much “a view” as “the class the builds the view”. It works like any other class and function, so you’re trying to reference a variable that wasn’t declared, with the expected result. Where `$identity` will be available to you is in places like `src/Template/Users/view.ctp` or, since you want it everywhere, `src/Template/Layout/default.ctp`. Those files are executed by the View class, in a context that’s been specially set up with all the variables that you’ve `set`.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 20, 2020, 4:35pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/12 "2020-04-20T16:35:18Z")

</div>

The default.php template is indeed the file I was looking for, containing the lay-out of the ‘Documentation’ and ‘API’. It’s hard to see the relation how the `$this->set()` in a Controller.php is enabling us through the View.php to have it available in the templates. The template comment gives a clue: \* @var \App\View\AppView $this

Anyway, I got it working, thanks again!

**To conclude for anyone that wants to do the same:**  
_AppController.php :_  
public function beforeRender(\Cake\Event\EventInterface $event){  
parent::beforeRender($event);  
$this-\>set(‘identity’, $this-\>request-\>getAttribute(‘identity’));  
}

_templates/layout/default.php :_  
in top PHP code section :  
`$logged_label = $identity ? $identity->get('email') : 'Not logged in';`  
and in div:  
`<div class="top-nav-links"> <?= $logged_label ?> </div>`

(_Direct PHP in the div does **not** seem to work_:  
`<div> <?= echo $identity ? $identity->get('email') : 'Not logged in'; ?> </div>` )

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 20, 2020, 4:57pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/13 "2020-04-20T16:57:47Z")

</div>

Not sure what’s not clear about controllers setting view variables. It’s [documented here](https://book.cakephp.org/3/en/controllers.html#setting-view-variables). The documentation is short, because it’s a pretty simple concept, I think.

Direct PHP should work fine. The problem is that `<?=` and `echo` are redundant. Either `<?php echo $identity...` or `<?= $identity...`

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 20, 2020, 5:07pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/14 "2020-04-20T17:07:37Z")

</div>

To make it more complete, I would like to let $logged\_lable refer to either the users view page or the login page.

I tried:

> $logged\_ref = $identity ? $this-\>[‘action’ =\> ‘view’,$user-\>($identity-\>get(‘id’)]) : $user-\>login() ;  
> `<a target="_blank" href=<?= $logged_ref ?>> <?= $logged_label ?> </a>`

since in `UserController.php` the view controller/function takes input `($id =null)`, I thought the following would make even less sense:  
`$logged_ref = $identity ? $this->['action' => 'view',$user->($identity->get('id')]) : $user->login() ;`

The error remains nevertheless `Record not found in table "users" with primary key [NULL]`

I don’t know if the HTML helper is a better solution, but since the Documentation and API are also designed by `<a>` I thought of keeping that consistent for layout.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 20, 2020, 5:28pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/15 "2020-04-20T17:28:05Z")

</div>

`$user->login()` will call the login function, not give you the login URL.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 20, 2020, 7:12pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/16 "2020-04-20T19:12:04Z")

</div>

Legit point. That made me solve it through “pure reference”, although I expected to make use of cakePHP automation methodology.

`$logged_label = $identity ? $identity->get('email') : 'Not logged in';`  
`$logged_ref=$identity ? "/users/view/".$identity->get('id') : "/users/login";`

`<a target="_blank" href=<?= $logged_ref ?>> <?= $logged_label ?> </a>`

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 20, 2020, 7:46pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/17 "2020-04-20T19:46:54Z")

</div>

Your actual code is now looking too complex to be well-served by the ternary operator. How about this:

```auto
if ($identity) {
    echo $this->Html->link($identity->get('email'),
        ['controller' => 'Users', 'action' => 'view', $identity->get('id')],
        ['target' => '_blank']
    );
} else {
    echo $this->Html->link('Not logged in',
        ['controller' => 'Users', 'action' => 'login'],
        ['target' => '_blank']
    );
}
```

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 21, 2020, 9:03am UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/18 "2020-04-21T09:03:10Z")

</div>

I have no knowledge about ternary operator performance, but your solution was indeed what I meant by using CakePHP methodology. I stored this code in a variable such that the code doesn’t need to be inside the html.

However, I don’t understand why this works and does not result in the same error of `Record not found in table "users" with primary key [NULL]` since I thought this was due to the view($id=null) in UserController.php.

So I see from this that the current user and the Users functions can be accessed through controller (whereas $user is unknown). I made a [new topic](https://discourse.cakephp.org/t/accessing-controller-authorization-through-template-view/7692) since I can’t apply similar access in the index View of Articles.

---

<div class="post-metadata">

**Author:** ![Zuluru](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/zuluru/32/1230_2.png) [@Zuluru](https://discourse.cakephp.org/u/Zuluru)\
**Post date:** [April 21, 2020, 2:05pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/19 "2020-04-21T14:05:59Z")

</div>

It’s not about the performance of the ternary operator, it’s about readability and maintainability of the code. This `if` is quite possible to write with the ternary operator, and the performance would likely be identical, but this version is much easier to understand at a glance.

You never said what specific line of code was causing the primary key error, so I can’t really comment on where that was coming from.

---

<div class="post-metadata">

**Author:** ![HypJ3U50N](https://yyz1.discourse-cdn.com/flex029/user_avatar/discourse.cakephp.org/hypj3u50n/32/1803_2.png) [@HypJ3U50N](https://discourse.cakephp.org/u/HypJ3U50N)\
**Post date:** [April 21, 2020, 9:24pm UTC](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666/20 "2020-04-21T21:24:33Z")

</div>

> [@Zuluru](#):
>
> You never said what specific line of code was causing the primary key error, so I can’t really comment on where that was coming from.

I mean this post above, mentioning the `Record not found in table "users" with primary key [NULL]` caused by intial try:

> [@HypJ3U50N](#):
>
> $logged\_ref = $identity ? $this-\>[‘action’ =\> ‘view’,$user-\>($identity-\>get(‘id’)]) : $user-\>login() ;  
> `<a target="_blank" href=<?= $logged_ref ?>> <?= $logged_label ?> </a>`

[Next page](https://discourse.cakephp.org/t/displaying-logged-in-user-in-header/7666.md?page=2)
