Plack::Middleware::Auth::DBIC ?

60 views
Skip to first unread message

Zbigniew Lukasiak

unread,
Jun 23, 2010, 4:36:39 PM6/23/10
to psgi-...@googlegroups.com
Hi there,

Is anyone working on a Middleware like that? It seems like an obvious idea:

1. If there is user_id in session - retrieve that user and put it in env
2. If there is login and password params in env - retrieve the user
from the db and check the password if it is correct put the user in
env

But then there comes the question - how the Middleware is supposed to
receive the DBIC schema class? In the environment?

Another question checking for password and login would require parsing
the QUERY_STRING (maybe using Plack::Request) - and then this effort
would most probably be redone by the application itself, can we avoid
that?

Cheers,
Zbigniew
http://brudnopis.blogspot.com/
http://perlalchemy.blogspot.com/

Tatsuhiko Miyagawa

unread,
Jun 23, 2010, 4:40:01 PM6/23/10
to psgi-...@googlegroups.com
My quick reaction to this is that this should be done in frameworks,
not as middleware.

On Wed, Jun 23, 2010 at 4:36 PM, Zbigniew Lukasiak <zzb...@gmail.com> wrote:
> Hi there,
>
> Is anyone working on a Middleware like that? It seems like an obvious idea:
>

--
Tatsuhiko Miyagawa

Tatsuhiko Miyagawa

unread,
Jun 23, 2010, 4:56:40 PM6/23/10
to psgi-...@googlegroups.com
To answer those questions from the generic middleware POV:

On Wed, Jun 23, 2010 at 4:36 PM, Zbigniew Lukasiak <zzb...@gmail.com> wrote:
>

> But then there comes the question - how the Middleware is supposed to
> receive the DBIC schema class?  In the environment?

The best practice is not to tied to any implementation of particular
classes, but instead let the middleware take callbacks. Instead of
specifying DBIC schema classes, let it take a callback that takes
user_id and password and return the boolean. That way your middleware
can work with non-ORM situation while if you use DBIC you can reuse
DBIC's API calls.

See how middleware like Session::DBI or Auth::Basic works. They always
use callbacks and/or OO duck typing, so it's extremely easy to adapt
to other class implementations as well as testing/mocking.

In general, writing a middleware component that works only with
particular implementation of modules and APIs is a bad idea.

>> Another question checking for password and login would require parsing
> the QUERY_STRING (maybe using Plack::Request) - and then this effort
> would most probably be redone by the application itself, can we avoid
> that?

Plack::Request caches the parsed output in PSGI env, and using
Plack::Request multiple times in the middleware chain as well as
frameworks won't take the penalty of reparsing. If the framework
doesn't use Plack::Req then yes, it will end up with multiple parsing.


--
Tatsuhiko Miyagawa

Zbigniew Lukasiak

unread,
Jun 24, 2010, 3:02:08 AM6/24/10
to psgi-...@googlegroups.com
First of all - I don't yet have any opinion of myself on this subject
- but I've seen other people talking about it
(http://www.sukria.net/fr/archives/2010/06/12/french-perl-workshop-2010-report/).
I just try to be careful.

On Wed, Jun 23, 2010 at 10:56 PM, Tatsuhiko Miyagawa <miya...@gmail.com> wrote:
> To answer those questions from the generic middleware POV:
>
> On Wed, Jun 23, 2010 at 4:36 PM, Zbigniew Lukasiak <zzb...@gmail.com> wrote:
>>
>> But then there comes the question - how the Middleware is supposed to
>> receive the DBIC schema class?  In the environment?
>
> The best practice is not to tied to any implementation of particular
> classes, but instead let the middleware take callbacks. Instead of
> specifying DBIC schema classes, let it take a callback that takes
> user_id and password and return the boolean. That way your middleware
> can work with non-ORM situation while if you use DBIC you can reuse
> DBIC's API calls.

I've looked at Plack::Middleware::Auth::Basic - and I think I
understand what you mean. So in our case it would be the callback
that does the retrieving of the user record and checking the password
there. It still means that we need the DBIC schema at the point of
defining the Middleware stack - and I think I'll agree with your first
email that this might not be the best solution.

Now - this probably would be a bit too many callbacks - but continuing
this functional programming approach - it would also be possible that
the Middleware puts a callback into the Environment - and later the
application uses it to get the user (or not) by applying it to the
DBIC schema (or if you want it to be more decoupled - to another
callback that would return something applicable to DBIC schema).

>
> See how middleware like Session::DBI or Auth::Basic works. They always
> use callbacks and/or OO duck typing, so it's extremely easy to adapt
> to other class implementations as well as testing/mocking.
>
> In general, writing a middleware component that works only with
> particular implementation of modules and APIs is a bad idea.
>
>>> Another question checking for password and login would require parsing
>> the QUERY_STRING (maybe using Plack::Request) - and then this effort
>> would most probably be redone by the application itself, can we avoid
>> that?
>
> Plack::Request caches the parsed output in PSGI env, and using
> Plack::Request multiple times in the middleware chain as well as
> frameworks won't take the penalty of reparsing. If the framework
> doesn't use Plack::Req then yes, it will end up with multiple parsing.
>

Thanks,
Zbigniew

Reply all
Reply to author
Forward
0 new messages