Skip to content

Latest commit

 

History

History
139 lines (105 loc) · 4.52 KB

Authenticate.md

File metadata and controls

139 lines (105 loc) · 4.52 KB

Authenticating login credentials

Well, we can't let just anybody into our secure website! We need to check that the username and password are correct. We also need somewhere for that login button to go.

We'll look at these 3 files

  • lib/SessionTutorial.pm
  • lib/SessionTutorial/Controller/Tutorial.pm
  • templates/tutorial/welcome.html.ep

lib/SessionTutorial.pm

Add

$r->post('/login')->name('do_login')->to('Tutorial#on_user_login');
  • explain the named route, do_login and the controller, Tutorial, where you need on_user_login

lib/SessionTutorial/Controller/Tutorial.pm

Add a new method called on_user_login to handle checking credentials

sub on_user_login {
  my $self = shift;

  my $username = $self->param('username');
  my $password = $self->param('password');

  if (check_credentials($username, $password)) {
    $self->stash(user => $username);
    $self->render(template => 'tutorial/welcome');
  } 
  else {
    $self->render(
        text => '<h2>Login failed</h2><a href="/login">Try again</a>',
        format => 'html',
        status => 403
    );
  }
}

sub check_credentials {
  my ($username, $password) = @_;

  if ( $username eq 'julian' && $password eq 'carax' ) {
    return 1;
  }

  return;
}

The form on the Login page POSTs the username and password to /login, so we need a route that directs the request to the on_user_login method in the Tutorial controller.

( note that "return" isn't required, but good form for chaining methods check this )

The check_credentials method separates the password check from the login action. This allows us to change the authentication method in future while maintaining the same login behaviour.

The quickest way of making sure you've got the right behaviour is to render to text, as in the failed login. Remember to set the format to html if you want to include a link. ( why is this not default ) The render used in the successful login directs the output to a template (which is composed of controller/action).

templates/tutorial/login.html.ep

fixed the form_for line to use the named route 'do_login'

We don't need a named route, but it can help you stay flexible as your site evolves. I'll talk more about this in Templates

templates/tutorial/welcome.html.ep

Added a new template as a landing page for successful logins, which is a good place to put messages and links to the content that the user can access.

TODO - talk briefly about templates

NOTES

OJO! - the on_user_login method needs you to return the rendered objects

works for render(text =>), but not render(msg) which needs a template, I think

add a landing page for successful login templates/tutorial/welcome.html.ep

END NOTES

Try it out

With the server running, click through the Login link on localhost:3000/ to get to the Login page

Test the app

Make sure the Authentication works correctly

I've renamed basic.t to 00_basic.t and copied it to 01_login.t to add the new tests. It now looks like

my $t = Test::Mojo->new('SessionTutorial');

$t->get_ok('/login')->status_is(200)->content_like(qr/Username/i);

# test successful login - julian carax
$t->post_ok('/login' => {Accept => '*/*'} => form => {username => 'julian', password => 'carax'})
  ->status_is(200)
  ->content_like(qr/Welcome, julian/i);

# test failed login - francisco fumero
$t->post_ok('/login' => {Accept => '*/*'} => form => {username => 'francisco', password => 'fumero'})
  ->status_is(403)
  ->content_like(qr/Login failed/i);

(are the Accept tests necessary?) Then run

script/session_tutorial test t/01_login.t

We've already seen the first test. The second posts valid credentials to the page, checks the return status and that we are Welcomed. The third test posts invalid credentials, checks that we get a 403 Authorization failed status and that we know the login failed.

Next Step

Now that we can successfully check credentials, let's make sure that we can maintain sessions and protect private pages from unauthorised users. Instructions continue in Sessions.

More information

More on forms and logins can be found on Oliver Günther's Applications with Mojolicious or have a look at the Mojolicious Cookbook on basic authentication

TODO - add link to explanations of GET/POST