# Saving the login state to the session

A session is when a user logs in up to when the user logs out. Vibe.d provides a mechanism to uses a session.

When we want to retrieve a particular record from the database, we simply use the **id** field as the key to retrieve the record by passing the key to the next page. When we retrieve another record, we lose this key because we receive another key.

But when a user logs in, the log in state needs to be saved for the duration of the session so that the user can navigate from page to page without having to log in again and again.

If the user is logged in, we should save that state so that as the user navigates from page to page, the system can check if the user is already logged in and is authorized to access that particular page. We need a session for that.

A variable, such as a logged-in state, can be saved to this session facility. Vibe.d has the session store for this purpose, of which there are two kinds: **MemorySessionStore** and the database-based store. For this project, we will use **MemorySessionStore.**

Edit **source\app.d**:

```d
import vibe.vibe;
import empcontrol;
void main()
{
  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  settings.bindAddresses = ["::1", "127.0.0.1"];
  settings.sessionStore = new MemorySessionStore;
  auto router = new URLRouter;
  router.get("*", serveStaticFiles("public/"));
  router.registerWebInterface(new EmployeeController);
  auto listener = listenHTTP(settings, router);
  scope (exit) listener.stopListening();
 
  runApplication();
}
```

Edit **source\empcontrol.d** to add a **User** struct.

```d
module empcontrol;
import vibe.vibe;
import empmodel;

struct User 
{
  bool loggedIn;
  string email;
}

class EmployeeController
{
  EmployeeModel empModel;
  string realm = "The Lorem Ipsum Company";
  private SessionVar!(User, "user") m_user;
  ...
```

And edit **postLogin()** to save the logged-in state to the session using the **m\_user** variable.

```d
  @errorDisplay!index
  void postLogin(string email, string password)
  {
    import vibe.http.auth.digest_auth;
   
    auto scrambled = createDigestPassword(realm, email, password);
    bool isAdmin = empModel.isAdmin(email, scrambled);
    enforce(isAdmin, "Email and password combination not found.");
    User user = m_user;
    user.loggedIn = true;
    user.email = email;
    m_user = user;
    redirect("all_employees");
  }
```

We created a **User** struct to hold the logged-in state

```d
struct User 
{
  bool loggedIn;
  string email;
}
```

Then we declared a session variable named **m\_user** of that struct type:

&#x20; `private SessionVar!(User, "user")`` `**`m_user;`**

Then we changed the value of **m\_user** inside **postLogin()** to save and start the session:

```d
    User user = m_user;
    user.loggedIn = true;
    user.email = email;
    m_user = user;
```

**Changing the value of m\_user automatically starts the session.**

We indicated that **index()** will be called and passed the error if **postLogin()** encounters an error:

```d
  @errorDisplay!index
  void postLogin(string email, string password)
  {
    import vibe.http.auth.digest_auth;
...
```

Then we changed the **index()** method to accept an **\_error** variable if **postLogin()** encounters an error.

```d
  void index(string _error = null)
  {
    string error = _error;
    render!("index.dt", error);
  }
```

Edit **views\index.dt** to display the error, if there is any, returned by the **enforce()** function.

```
extends layout
block maincontent
  h2 The Lorem Ipsum Company
  -if(error)
    div.error-div
      span.error-message #{error}
  div.
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
    Nam nec urna arcu. Quisque eleifend posuere vestibulum.
    In sed magna mauris. Phasellus bibendum ligula et placerat
    vulputate. In non suscipit lectus, a laoreet odio. Donec
    at sapien eu nisi porta condimentum. Morbi non varius ex,
    nec luctus nisl. Aenean varius dui quis arcu auctor luctus.
    Integer efficitur ornare massa, ac suscipit enim sagittis et.
    Proin vestibulum tellus in ipsum ultrices, sed imperdiet
    sapien euismod. Praesent vel facilisis mauris. Proin finibus
    congue tellus, non varius ante. Nullam tincidunt dolor felis.
    Pellentesque non luctus tellus. Curabitur et sapien at justo
    fringilla feugiat et a erat.
    <br /><br />
```

Compile, run and refresh the browser. Click on the Login menu item and input a non-existing admin user. If you get an error, that means the error-trapping mechanism is working.

Now let us make the other pages know about the login state.
