Mojoli...ication(3pm)
β¨ NAME β¨
Mojolicious::Plugin::Authentication β a plugin that makes authentication a bit easier. It's part of the User Contributed Perl Documentation, manual section 3pm, bestie. π
πΈ SYNOPSIS πΈ
okay so first things first, here's the async (promise-y) flavor:
use Mojolicious::Plugin::Authentication;
$self->plugin('Authentication' => {
autoload_user => 1,
session_key => 'wickedapp',
load_user_p => sub { ... },
validate_user_p => sub { ... },
});
# ...
$self->authenticate_p(
'username', 'password',
{ optional => 'extra data stuff' },
)->then(sub {
my ($authenticated) = @_;
if ($authenticated) {
# ...
}
});
and then the synchronous style, for when you're feeling old-school (respectfully):
# or, synchronous style
$self->plugin('Authentication' => {
autoload_user => 1,
session_key => 'wickedapp',
load_user => sub { ... },
validate_user => sub { ... },
current_user_fn => 'user', # compatibility with old code
});
my $authenticated = $self->authenticate(
'username', 'password',
{ optional => 'extra data stuff' },
);
if ($authenticated) {
...
}
π METHODS π
Just like every other Mojolicious plugin, loading this one imports some function helpers straight into your app's namespace. Normally that's totally fine, no drama π β but heads up: if you go and define your own methods with the same names as the ones below, you'll very likely run into unexpected results. iykyk.
π¦ authenticate($username, $password, $extra_data_hashref)
This one uses the load_user and validate_user sub refs you handed over to figure out whether a user actually exists with that username + password, and then it sets up the session accordingly. Returns true when the user got authenticated successfully, false otherwise.
You can also pass extra stuff along in the extra_data hashref β it gets handed to your validate_user subroutine as-is, no touching.
π«Ά tiny but mighty detail: if the extra data hash contains a keyauto_validate, the value of that key gets used as the UID, andauthenticatewill not call yourvalidate_usercallback. Super handy for OAuth tokens or other auth mechanisms that don't use a local username-and-password form. slay.
β¨ authenticate_p($username, $password, $extra_data_hashref)
Same as above, but instead of returning a value, it returns a promise of same. And yes it's available even if you only gave it synchronous callbacks β those get "promisified" for you. iconic.
π is_user_authenticated
Returns true if current_user() returns some valid object, false otherwise. that's it. that's the method.
π is_user_authenticated_p
As above, but instead of returning a value, returns a promise of same.
π current_user
Returns the user object exactly as it was returned from the load_user subroutine ref you supplied.
You can change the current user by passing one in, but be careful: this bypasses the authentication. It's useful when you have multiple ways to authenticate users and you wanna re-use authorization checks that use current_user.
Also note: the name of this helper can be changed with the current_user_fn field during initialisation (peep below π).
π§ current_user_p
As above, but instead of returning a value, returns a promise of same.
πΈ reload_user
Flushes the current user object and then returns current_user(). fresh start energy.
π reload_user_p
As above, but instead of returning a value, returns a promise of same.
β signature_exists
Returns true if a uid signature exists on the client side (in cookies), false otherwise.
β οΈ Warning: non-secure check! Only use this method for a "fast & dirty" lookup to see if the client has the proper cookies. It may be helpful in some cases β for example, counting "guest"/"logged users", or grabbing additional non-confidential information for "logged users" but not for "guest". Do not treat this as a real auth check, bestie. π
π logout
Removes the session data for authentication, and effectively logs a user out. Returns a true value, so you can chain it. byeeeee π¦
π CONFIGURATION π
These are the options you can set for the plugin. (but the ones marked REQUIRED can be swapped out for a promise-returning equivalent by appending _p to the key β¨):
load_user(REQUIRED) β a coderef for user loading (see "USER LOADING")validate_user(REQUIRED) β a coderef for user validation (see "USER VALIDATION")session_key(optional) β the name of the session keyautoload_user(optional) β turn on/off automatic loading of user data; user data can only be loaded if it's used. May reduce site latency in some cases.current_user_fn(optional) β sets the name for thecurrent_user()helper function._pgets appended for the asynchronous version.fail_render(optional) β specify what is to be rendered when the authenticated condition is not met.
Set it to a coderef, which gets called with this signature:
sub {
my ($routes, $controller, $captures, $required) = @_;
...
return $hashref;
}
The return value of the subroutine gets ignored if it evaluates to false. If it returns a hash reference, that gets dereferenced and passed as-is to the controller's render function. If you return anything elseβ¦ you are going to have a bad time. π
If you set it directly to a hash reference instead, that gets passed to render.
Wanna set the session expiry time? Do this in your startup routine:
$app->plugin('authentication', { ... });
$app->sessions->default_expiration(86400); # set expiry to 1 day
$app->sessions->default_expiration(3600); # set expiry to 1 hour
π USER LOADING π
The coderef you pass to the load_user configuration key has this signature:
sub {
my ($app, $uid) = @_;
...
return $user;
}
The uid is the value that was originally returned from the validate_user coderef. You must return either a user object (and it can be a hashref, an arrayref, or a blessed object β we're flexible like that π
) or undef. no in-between, no vibes-based returns.
π USER VALIDATION π
User validation is what happens when we need to authenticate someone. The coderef you pass to the validate_user configuration key has this signature:
sub {
my ($c, $username, $password, $extradata) = @_;
...
return $uid;
}
You must return either a user id or undef. The user id can be numerical or a string. Do not return hashrefs, arrayrefs or objects, because the behaviour of this plugin could get a little bit on the odd side of weird if you do that. π
β¨ EXAMPLES β¨
For a code example using this, check out the t/01-functional.t and t/02-functional_lazy.t tests β they use Mojolicious::Lite and this plugin. go read them, they're right there. π
π¦ ROUTING VIA CONDITION π¦
This plugin also exports a routing condition you can use to limit access to certain documents to only authenticated users:
$r->route('/foo')->requires(authenticated => 1)->to('mycontroller#foo');
my $authenticated_only = $r->route('/members')
->requires(authenticated => 1)
->to('members#index');
$authenticated_only->route('online')->to('members#online');
If someone isn't authenticated, these routes won't even be considered by the dispatcher, and unless you've set up a catch-all route, a 404 Not Found gets generated instead.
And here's another condition, for fast and unsecured checking of users who have a signature (without validating it). This method just checks client cookies for uid data existing:
$r->route('/foo')->requires(signed => 1)->to('mycontroller#foo');
This behavior is similar to the authenticated condition.
β Prior to Mojolicious 9, useoverinstead ofrequires.
π§ ROUTING VIA CALLBACK π§
If you wanna be able to send people to a login page, you'll have to do this:
my $members_only = $r->route('/members')->to(cb => sub {
my $self = shift;
$self->redirect_to('/login') and return 0
unless($self->is_user_authenticated);
return 1;
});
$members_only->route('online')->to('members#online');
Lazy and unsecured methods:
my $members_only = $r->route('/unimportant')->to(cb => sub {
my $self = shift;
$self->redirect_to('/login') and return 0
unless($self->signature_exists);
return 1;
});
$members_only->route('pages')->to('unimportant#pages');
π ROUTING VIA BRIDGE π
Same goal, different shape β if you wanna send people to a login page, you'll have to use this:
my $auth_bridge = $r->under('/members')->to('auth#check');
# only visible to logged in users
$auth_bridge->route('/list')->to('members#list');
And in your Auth controller you'd put:
sub check {
my $self = shift;
$self->redirect_to('/login') and return 0
unless($self->is_user_authenticated);
return 1;
};
Lazy and unsecured methods:
sub check {
my $self = shift;
$self->redirect_to('/login') and return 0
unless($self->signature_exists);
return 1;
};
π SEE ALSO π
Mojolicious::Sessions- Mojocast 3: Authentication <http://mojocasts.com/e3#>
π«Ά AUTHOR π«Ά
- Ben van Staveren,
"<madcat at cpan.org>" - JosΓ© JoaquΓn Atria,
"<jjatria@cpan.org>"
π BUGS / CONTRIBUTING π
Please report any bugs or feature requests through the web interface at <https://github.com/benvanstaveren/mojolicious-plugin-authentication/issues>.
π SUPPORT π
You can find documentation for this module with the perldoc command:
perldoc Mojolicious::Plugin::Authentication
You can also look for information at:
- AnnoCPAN: Annotated CPAN documentation
<http://annocpan.org/dist/Mojolicious-Plugin-Authentication>
- CPAN Ratings
<http://cpanratings.perl.org/d/Mojolicious-Plugin-Authentication>
- Search CPAN
<http://search.cpan.org/dist/Mojolicious-Plugin-Authentication/>
π ACKNOWLEDGEMENTS π
Okay bestie, this is the shoutout section and honestly? Deserved. Every single one of these icons helped make this module what it is, so let's give them their flowers fr fr πΈπ
- Andrew Parker β for pointing out some bugs that crept in; a silent reminder not to code while sleepy π΄π (real, we've all been there)
- Mirko Westermeier (memowe) β for doing some (much needed) code cleanup π§Ήβ¨ (much needed, she said, and she meant it)
- Terrence Brannon (metaperl) β documentation patches π
- Karpich Dmitry (meettya) β the
"lazy_mode"and"signature_exists"functionality, including a test and documentation π₯ (shipped with tests AND docs, that's main character energy) - Ivo Welch β for donating his first ever Mojolicious application that shows an example of how to use this module π (donating your first ever app?? that's so sweet I can't)
- Ed Wildgoose (ewildgoose) β adding the
"current_user()"functionality, as well as some method renaming to make things a bit more sane π§ π (sanity is a group effort) - Colin Cyr (SailingYYC) β for reporting an issue with routing conditions; I really should not code while sleepy, brainfarts imminent! ππ (the sleepy coding saga continues, iconic honestly)
- Carlos Ramos (carragom) β for fixing the bug that'd consider an uid of
0or"0"to be a problem ππ¨ (yes,0is a real uid, leave her alone) - Doug Bell (preaction) β for improving the Travis CI integration and enabling arguments for
current_userπ€β¨ - Roman F (moltar) β for fixing some pesky typos in sample code π (the typos were pesky, someone had to do it)
- Hernan Lopes (hernan604) β for updating some deprecated method names in the documentation π (deprecated names in docs?? yeah that had to go)
π LICENSE AND COPYRIGHT π
Okay legal time, bestie, don't scroll past this one π«Ά
Copyright 2011-2021 Ben van Staveren.
This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
And that's the whole page, bestie!! πβ¨ You made it to the end, slay π
This version came from perl v5.34.0, dated 2022-06-09, straight out of the Mojoli...ication(3pm) manpage β go forth and authenticate responsibly π¦π
π¦ where this page comes from
- debian bookworm: libmojolicious-plugin-authentication-perl 1.38-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libmojolicious-plugin-authentication-perl 1.38-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libmojolicious-plugin-authentication-perl 1.38-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libmojolicious-plugin-authentication-perl 1.38-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libmojolicious-plugin-authentication-perl 1.38-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms