On Saturday 29 May 2010 02:28:44 Daniel Pittman wrote:
One of the requirements I am going to hit in the near future is that we will need to provide some public and some routes inside a single application.
A pretty common requirement :)
When users hit anything under a specific path, basically, they need to have an already validated login, or else we need to send 'em off to get one. The most basic "implement a login form" style thing pattern, nothing fancy.
There's an example of doing this in the Dancer Cookbook: http://search.cpan.org/dist/Dancer/lib/Dancer/Cookbook.pod#Sessions_and_logg... [...]
My current model is to provide a plugin akin to this: [...] That then gets used with a route like this:
get '/example/:arg' => with_auth { # normal handler here };
That looks quite useful - you might want to consider releasing that to CPAN :)
I considered the approach of hooking all requests and performing my own URL matching to determine if they should require authentication, but that seems to require that I duplicate an awful lot of code from the Dancer route system.
Yes, if all the bits that should be protected aren't under a common prefix, then you would be duplicating some info, but otherwise, using a before handler to do it is easy...
Oh. I did consider this construction, but found it hard to get right, especially if I wanted to cover '/admin' as well as pages under it.
get r('/admin/.*') => sub { session('user') or redirect '/login', 302; pass; };
get '/admin/example' => sub { # ...should only be called *after* the first route calls 'pass' };
Is that just my messing up or something?
What you're trying to do there would be better handled with a before filter. You could base it upon the example given in the cookbook: http://search.cpan.org/dist/Dancer/lib/Dancer/Cookbook.pod#Sessions_and_logg... but change the before filter to, e.g.: before sub { if (! session('user') && request->path_info =~ m{/admin/}) { var requested_path => request->path_info; request->path_info('/login'); } }; So, any request to a path starting with /admin/ gets sent to the /login route instead. (It's basically what you had, but using a before filter rather than a route which has to pass). Hope this helps a bit? Cheers Dave P -- David Precious <davidp@preshweb.co.uk> http://blog.preshweb.co.uk/ www.preshweb.co.uk/twitter www.preshweb.co.uk/linkedin www.preshweb.co.uk/facebook www.preshweb.co.uk/identica www.lyricsbadger.co.uk "Programming is like sex. One mistake and you have to support it for the rest of your life". (Michael Sinz)