Create a Login Page for a Losant Experience

In the previous part of this walkthrough, you learned how to create a layout. This part covers creating a log in page that will be rendered in that layout. This page allows your experience users to log in and make authenticated requests to other pages within your experience.

Screenshot

Step One: Use Experience Endpoints

The URLs that a user can request are called Experience Endpoints. Whenever an endpoint is requested, an Experience Workflow is triggered with that request. That workflow can then reply with data (you’re building an API) or with a page. Pages are the main entry point for your custom experiences.

Define two endpoints that allow users to log in to your experience. The first, GET /login, returns the form with the email and password fields. The second, POST /login, accepts the credentials from the form, authenticates the user, and sets a cookie in their browser for future requests.

You can define endpoints under “Endpoints”.

Endpoints

Important

Losant provides an Endpoint Wizard to create and configure your new endpoint as well as any new pages or workflows necessary to utilize it: Endpoint Wizard The purpose of this guide is to walk through all of the steps. The instructions to follow assume that you select 'Custom': Endpoint Wizard Page One

  1. Click the “Add” button on the top right of the endpoints list to add the new GET /login endpoint.

Log in Endpoint

  1. Set the Method to GET.
  2. Set the Route to /login.
  3. Change Access Control to All public users.

Access control defines who is allowed to request this endpoint. Since this is the login route, this needs to be set to All public users because no one is logged in yet.

  1. Click the “Save Endpoint” button to create this endpoint.

Repeat the same process again for the POST /login route, but set the Method to POST. At this point you will have two endpoints defined.

Step Two: Create Experience Views

By themselves, endpoints have no functionality until a workflow is triggered. The workflow that powers these two endpoints returns the login page. For that to happen, you must first create the page.

Add Page

Page Content

Pages work similarly to the layouts and components you’ve already seen. Each one requires a name and content. Unlike layouts and components, however, pages also accept a layout. When this page is requested, this is the layout that it will be rendered into.

The content for this example is here:

{{#fillSection "metaDescription"}}This is an example login page for your application experience.{{/fillSection}}
<div class="container-fluid">
  <div class="row">
    <div class="col-xs-12 col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-4 col-lg-offset-4">
      <div style="max-width: 300px; margin: 0 auto 20px; text-align: center;">
        <img class="img-responsive" src="https://app.losant.com/images/kanarra/kanarra_full.png" alt="Big Logo">
      </div>
      <div class="well">
        <p>
          Welcome to your example Experience View! The above logos and this content
          can be customized by editing the example <a target="_blank" href="https://docs.losant.com/experiences/views/#layouts">Layout</a>, <a target="_blank" href="https://docs.losant.com/experiences/views/#pages">Pages</a>, and <a target="_blank" href="https://docs.losant.com/experiences/views/#components">Components</a>
          that were automatically generated for you.
        </p>
        <p>
          Log in below with your example user to see the next page with
          additional information.
        </p>
      </div>
      {{#if pageData.loginFailure}}
        {{component "errorAlert" "Incorrect email or password."}}
      {{/if}}
      <form method="post">
        <div class="form-group">
          <label for="email">Email address</label>
          <input autofocus required value="{{ pageData.email }}" type="email" class="form-control" name="email" id="email" placeholder="e.g. test.user@example.com">
        </div>
        <div class="form-group">
          <label for="password">Password</label>
          <input required minlength="8" maxlength="255" type="password" class="form-control" id="password" name="password">
        </div>
        <button type="submit" class="btn btn-success">Sign In</button>
      </form>
    </div>
  </div>
</div>

Most of the content in this page is Twitter Bootstrap markup.

fillSection Helper

The first line on this example page uses a special fillSection Handlebar helper to replace the description tag in the layout’s header.

{{#fillSection "metaDescription"}}This is an example login page for your
application experience.{{/fillSection}}

Sections allow you to define areas within a layout that your pages can replace. This example uses a section to allow pages to override the description meta tag in the layout’s header.

Handling Errors

Farther down in the page’s content, you’ll see a new errorAlert component.

{{#if pageData.loginFailure}} {{component "errorAlert" "Incorrect email or
password."}} {{/if}}

This is the first use of the pageData object on the context. This is the custom data that’s added to the context by the workflow that was triggered by the endpoint request. If the email and password were invalid, the workflow sets a loginFailed property on the context and returns the page back to the user. This section checks if that field is set and displays the errorAlert component if it is.

Create the errorAlert component using the content provided below:

<div class="alert alert-danger">
  {{.}}
</div>

Similar to the gaTracking component from the previous section, the context is being overridden with the passed-in message. This means the errorAlert can display the message using the {{.}} template, since the entire context is set to the error string.

Log In Form

The rest of the page’s content is the actual form that allows the user to enter an email and password, then submit them to the POST /login endpoint you defined earlier.

<form method="post">
  <div class="form-group">
    <label for="email">Email address</label>
    <input
      autofocus
      required
      value="{{ pageData.email }}"
      type="email"
      class="form-control"
      name="email"
      id="email"
      placeholder="e.g. test.user@example.com"
    />
  </div>
  <div class="form-group">
    <label for="password">Password</label>
    <input
      required
      minlength="8"
      maxlength="255"
      type="password"
      class="form-control"
      id="password"
      name="password"
    />
  </div>
  <button type="submit" class="btn btn-success">Sign In</button>
</form>

This is Twitter Bootstrap boilerplate form markup. Notice is the {{ pageData.email }} template. The pageData.email field is set by the workflow if the login attempt fails so that the email field is still filled in for the user.

At this point you have the endpoints and the page. You now need the workflow that gets triggered by the endpoint requests, which replies with the page you just created.

Step Three: Create an Experience Workflow

First, download the example workflow and import it as a new experience workflow.

Workflow

You’ll notice that the workflow is disabled. Before you can use this workflow, you need to enable it and configure a few settings in various nodes to use your newly created endpoints and login page.

  1. Click the two endpoint triggers at the top and set the Endpoint Method / Route to the corresponding endpoints you created earlier.

Edit Triggers

  1. Edit the two Endpoint Reply nodes and set the Page Template field to your newly created Log In page.

Edit Replies

This workflow triggers for both the GET /login and POST /login endpoints. Once triggered, this workflow does the following tasks:

  • Checks to see if a user is already logged in. If a user is logged in, the experience.user payload path will be automatically filled in with the user’s details.
  • If a user is logged in, the workflow replies with a redirect to /, which is the home page that’s created in the next part of this walkthrough.
  • If the user is not logged in, the workflow then checks whether its handling the GET or POST request.
  • If it’s the GET request, the workflow replies with the Log In page you just created.
  • If it’s the POST request, the workflow uses the Authenticate node to check if the email and password provided by the user are valid.
  • If the authentication fails, the workflow replies with the Log In page again, but this time it sets the loginFailure and email fields. These are used to display an error to the user and prepopulate the email field so the user doesn’t have to retype it.
  • If the authentication succeeds, the user is redirected to the home page. The reply node also sets an authorization cookie set to the user’s authentication token, which was obtained from the previous Authentication node. The browser automatically sends this cookie with each subsequent request, so Losant can keep the user logged in during their session.

After deploying this workflow, you can now test the page by requesting your /login endpoint. If you don’t already have an Experience User, create one you can log in with.

After you log in, the above workflow attempts to redirect you to /, which hasn’t been defined yet. This means you’ll get an error message. In the next part of this workflow, you’ll create the home page that’s only accessible to authenticated users.

Was this page helpful?


Still looking for help? You can also search the Losant Forums or submit your question there.