Dancer2

 view release on metacpan or  search on metacpan

lib/Dancer2/Manual/Cookbook.pod  view on Meta::CPAN


    # add in bookstore/lib/Bookstore.pm
    sub _perform_search {
        my ($query) = @_;
        my $bookstore_schema = schema 'Bookstore';
        my @results;
        # search in authors
        my @authors = $bookstore_schema->resultset('Author')->search({
            -or => [
                firstname => { like => "%$query%" },
                lastname  => { like => "%$query%" },
          ]
        });
        push @results, map {
            { author => join(' ', $_->firstname, $_->lastname),
                books => [],
            }
        } @authors;
        my %book_results;
        # search in books
        my @books = $bookstore_schema->resultset('Book')->search({
            title => { like => "%$query%" },
        });
        foreach my $book (@books) {
            my $author_name = join(' ', $book->author->firstname, $book->author->lastname);
            push @{$book_results{$author_name}}, $book->title;
        }
        push @results, map {
            { author => $_,
              books => $book_results{$_},
            }
        } keys %book_results;
        return @results;
    }

=item * Use home made schema classes

The L<DBIx::Class::MooseColumns> lets you write the DBIC schema classes
using L<Moose>. The schema classes should be put in a place that Dancer2
will find. A good place is in F<bookstore/lib/>.

Once your schema classes are in place, all you need to do is modify F<config.yml>
to specify that you want to use them, instead of the default auto-detection method:

    # change in bookstore/config.yml
    plugins:
      DBIC:
        bookstore:
          schema_class: My::Bookstore::Schema
          dsn: "dbi:SQLite:dbname=bookstore.db"

=back

Our bookstore lookup application can now be started using the built-in server:

    # start the web application
    plackup bin/app.psgi

=head1 Authentication Recipes

Writing a form for authentication is simple: we check the user credentials
on a request and decide whether to continue or redirect them to a form.
The form allows them to submit their username and password; we save that
and create a session for them so when they try the original request,
we recognize the user and allow them in.

=head2 Basic Application

The application is fairly simple. We have a route that needs authentication,
we have a route for showing the login page, and we have a route for posting
login information and creating a session.

     package MyApp;
     use Dancer2;

     get '/' => sub {
         session('user')
             or redirect('/login');

         template index => {};
     };

     get '/login' => sub {
         template login => {};
     };

     post '/login' => sub {
         my $username  = query_parameters->get('username');
         my $password  = query_parameters->get('password');
         my $redir_url = query_parameters->get('redirect_url') || '/login';

         $username eq 'john' && $password eq 'correcthorsebatterystaple'
             or redirect $redir_url;

         session user => $username;
         redirect $redir_url;
     };

=head2 Tiny Authentication Helper

L<Dancer2::Plugin::Auth::Tiny> allows you to abstract away not only the
part that checks whether the session exists, but to also generate a
redirect with the right path and return URL.

We simply have to define what routes needs a login using Auth::Tiny's
C<needs> keyword.

     get '/' => needs login => sub {
         template index => {};
     };

It creates a proper return URL using C<uri_for> and the address from which
the user arrived.

We can thus decorate all of our private routes to require authentication in
this manner. If a user does not have a session, it will automatically forward
it to I</login>, in which we would render a form for the user to send a login request.

Auth::Tiny even provides a new parameter, C<return_url>, which can be used to send
the user back to their original requested path.



( run in 1.892 second using v1.01-cache-2.11-cpan-39bf76dae61 )