root/lang/perl/Catalyst-Controller-RequestToken/trunk/lib/Catalyst/Controller/RequestToken.pm @ 13221

Revision 13221, 3.6 kB (checked in by hidek, 5 years ago)

initial import

Line 
1package Catalyst::Controller::RequestToken;
2
3use strict;
4use warnings;
5
6use base qw(Catalyst::Controller);
7
8our $VERSION = '0.01';
9
10__PACKAGE__->config(
11        session_name => '_token',
12        request_name => '_token',
13);
14
15sub ACCEPT_CONTEXT {
16    my ( $self, $c ) = @_;
17
18    return bless { %$self, c => $c }, ref($self);
19}
20
21sub new {
22    my $class = shift;
23    my $self  = $class->NEXT::new(@_);
24
25    $self->_setup(@_);
26    return $self;
27}
28
29sub _setup {
30    my $self = shift;
31    my ($c) = @_;
32
33    $self->config(%{$self->config}, %{$c->config->{'Controller::RequestToken'}});
34
35    Catalyst::Exception->throw("Catalyst::Plugin::Session is required")
36        unless $c->isa('Catalyst::Plugin::Session');
37}
38
39sub validate_token {
40    my $self = shift;
41
42    return $self->{c}->stash->{validate_token};
43}
44
45sub _parse_CreateToken_attr {
46    my ( $self, $app_class, $action_name, $vaue, $attrs ) = @_;
47
48    return ( ActionClass => 'Catalyst::Controller::RequestToken::Action::CreateToken' );
49}
50
51sub _parse_ValidateToken_attr {
52    my ( $self, $app_class, $action_name, $vaue, $attrs ) = @_;
53
54    return ( ActionClass => 'Catalyst::Controller::RequestToken::Action::ValidateToken' );
55}
56
57=head1 NAME
58
59Catalyst::Controller::RequestToken - Handling transaction token across forms
60
61=head1 SYNOPSIS
62
63requires Catalyst::Plugin::Session module, in your application class:
64
65    use Catalyst qw/
66        Session
67        Session::State::Cookie
68        Session::Store::FastMmap
69        FillForm
70     /;
71
72in your controller class:
73
74    use base qw(Catalyst::Controller::RequestToken);
75
76    sub form :Local {
77        my ($self, $c) = @_;
78
79        $c->stash->{template} = 'form.tt';
80        $c->forward($c->view('TT'));
81    }
82
83    sub confirm :Local :CreateToken {
84        my ($self, $c) = @_;
85
86        $c->stash->{template} = 'confirm.tt';
87        $c->forward($c->view('TT'));
88    }
89   
90    sub complete :Local :ValidateToken {
91        my ($self, $c) = @_;
92
93        if ($self->validate_token) {
94            $c->response->body('complete.');
95        } eles {
96            $c->response->body('invalid operation.');
97        }   
98    }
99
100templates:
101
102form.tt
103    <html>
104    <body>
105    <form action="confirm" method="post">
106    <input type="submit" name="submit" value="confirm"/>
107    </form>
108    </body>
109    </html>
110
111confirm.tt
112    <html>
113    <body>
114    <form action="complete" method="post">
115    <input type="hidden" name="_token" values="[% c.req.param('_token') %]"/>
116    <input type="submit" name="submit" value="complete"/>
117    </form>
118    </body>
119    </html>
120
121=head1 DESCRIPTION
122
123This controller enables to enforcing a single transaction across multi forms.
124Using token, you can prevent duplicate submits, or protect from CSRF atack.
125
126This module REQUIRES Catalyst::Plugin::Session to store server side token.
127
128If you add CreateToken attribute to action, token will be created and stored
129into request and session. You can return a content with request token which
130should be posted to server.
131
132If you add ValidateToken attribute, this will validate request token with
133sever-side session token, and remove token from session.
134
135After ValidateToken, there is any token in session, so validation will be
136failed, if user request with expired token.
137
138=head1 METHODS
139
140=item validate_token
141
142Return token is valid or not.  This will work collectlly only after
143ValidateToken.
144
145=head1 SEE ALSO
146
147L<Catalyst>, L<Catalyst::Plugin::Session>, L<Catalyst::Plugin::FormValidator::Simple>
148
149=head1 AUTHOR
150
151Hideo Kimura <hideo.kimura@kddi-web.com>
152
153=head1 COPYRIGHT
154
155This program is free software; you can redistribute
156it and/or modify it under the same terms as Perl itself.
157
158The full text of the license can be found in the
159LICENSE file included with this module.
160
161=cut
162
1631;
Note: See TracBrowser for help on using the browser.