You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by will trillich <wi...@serensoft.com> on 2001/04/30 21:31:02 UTC

forbidden vs. cookie

i could really use some dumbed-down tips on setting cookies
during a redirect. boy, this is really getting to me.

using apache 1.3.9 on debian 2.2/potato

in trying to implement the concept of the Apache::Ticket*.pm
modules from the Apache Modules (eagle) book in chapter 6
(on pages 304+) i'm running into browser compatibility problems.
SOME browsers (differs among platforms, too) see the forbidden or
redirect codes and take action immediately, ignoring any
set-cookie headers that are also sent.

as a workaround, i was trying to change TicketAccess.pm to

	# the munged version trying to accomodate rude browsers:
	package Apache::TicketAccess;

	use strict;
	use Apache::Constants qw(OK FORBIDDEN REDIRECT);
	use Apache::TicketTool ();

	sub handler {
		my $r = shift;
		my $ticketTool = Apache::TicketTool->new($r);
		my($result, $msg) = $ticketTool->verify_ticket($r);
		unless ($result) {
			$r->log_reason($msg, $r->filename);
			my $cookie = $ticketTool->make_return_address($r);

	#the original code that works for SOME browsers:
	#		$r->err_headers_out->add('Set-Cookie' => $cookie);
	#		return FORBIDDEN;

			my $login_uri = $r->dir_config("TicketLogin");

	# as AccessHandler, this was very much a bad idea:
	#		use CGI '-autoload';
	#		print
	#			header(-refresh => "1; URL=$login_uri", -cookie => $cookie),
	#			start_html(-title => 'Redirecting to login', -bgcolor => 'white'),
	#			h1('Gotta log in, first'),
	#			p("You're being redirected to ",
	#				a({-href=>$login_uri},$login_uri),
	#				" in just a moment."),
	#			h2("Please stand by..."),
	#			end_html();
	#		return OK;
	# it does manage to redirect the browser but there's lots
	# of duplicated headers and garbage (plus just hitting the
	# BACK button bypassed the need to log in)

	# this don't work so not, neither:
			$r->header_out(-cookie=>$cookie);
			$r->header_out(-location=>$login_uri);
			return REDIRECT;
	# neither header is sent.

		}
		return OK;
	}

	1;
	__END__

i've spent hours flipping back and from from the index to the
text, slapping postit notes on every other page, scanning
Apache::*.pm source code -- and it's still not sinking in... a
little help would be appreciated!

AAUGH!

-- 
will@serensoft.com

Re: forbidden vs. cookie

Posted by Tim Tompkins <ti...@arttoday.com>.
Here's another option which may not be exactly what you're looking for, but
it will work:  Once you've performed all validation and are ready to
redirect them with the cookie, rather than attempting the redirect with http
headers, just output a simple "processing" page with the redirect url in an
http-equiv meta tag.  The cookie will get set on the processing page and
then the browser will request the redirect itself.


Thanks,

Tim Tompkins
----------------------------------------------
Staff Engineer / Programmer
http://www.arttoday.com/
----------------------------------------------
----- Original Message -----
From: "will trillich" <wi...@serensoft.com>
To: <mo...@apache.org>
Sent: Monday, April 30, 2001 12:31 PM
Subject: forbidden vs. cookie


> i could really use some dumbed-down tips on setting cookies
> during a redirect. boy, this is really getting to me.
>
> using apache 1.3.9 on debian 2.2/potato
>
> in trying to implement the concept of the Apache::Ticket*.pm
> modules from the Apache Modules (eagle) book in chapter 6
> (on pages 304+) i'm running into browser compatibility problems.
> SOME browsers (differs among platforms, too) see the forbidden or
> redirect codes and take action immediately, ignoring any
> set-cookie headers that are also sent.
>
> as a workaround, i was trying to change TicketAccess.pm to
>
> # the munged version trying to accomodate rude browsers:
> package Apache::TicketAccess;
>
> use strict;
> use Apache::Constants qw(OK FORBIDDEN REDIRECT);
> use Apache::TicketTool ();
>
> sub handler {
> my $r = shift;
> my $ticketTool = Apache::TicketTool->new($r);
> my($result, $msg) = $ticketTool->verify_ticket($r);
> unless ($result) {
> $r->log_reason($msg, $r->filename);
> my $cookie = $ticketTool->make_return_address($r);
>
> #the original code that works for SOME browsers:
> # $r->err_headers_out->add('Set-Cookie' => $cookie);
> # return FORBIDDEN;
>
> my $login_uri = $r->dir_config("TicketLogin");
>
> # as AccessHandler, this was very much a bad idea:
> # use CGI '-autoload';
> # print
> # header(-refresh => "1; URL=$login_uri", -cookie => $cookie),
> # start_html(-title => 'Redirecting to login', -bgcolor => 'white'),
> # h1('Gotta log in, first'),
> # p("You're being redirected to ",
> # a({-href=>$login_uri},$login_uri),
> # " in just a moment."),
> # h2("Please stand by..."),
> # end_html();
> # return OK;
> # it does manage to redirect the browser but there's lots
> # of duplicated headers and garbage (plus just hitting the
> # BACK button bypassed the need to log in)
>
> # this don't work so not, neither:
> $r->header_out(-cookie=>$cookie);
> $r->header_out(-location=>$login_uri);
> return REDIRECT;
> # neither header is sent.
>
> }
> return OK;
> }
>
> 1;
> __END__
>
> i've spent hours flipping back and from from the index to the
> text, slapping postit notes on every other page, scanning
> Apache::*.pm source code -- and it's still not sinking in... a
> little help would be appreciated!
>
> AAUGH!
>
> --
> will@serensoft.com
>


Re: forbidden vs. cookie

Posted by Robert Landrum <rl...@capitoladvantage.com>.
>i could really use some dumbed-down tips on setting cookies
>during a redirect. boy, this is really getting to me.
>
>using apache 1.3.9 on debian 2.2/potato
>
>in trying to implement the concept of the Apache::Ticket*.pm
>modules from the Apache Modules (eagle) book in chapter 6
>(on pages 304+) i'm running into browser compatibility problems.
>SOME browsers (differs among platforms, too) see the forbidden or
>redirect codes and take action immediately, ignoring any
>set-cookie headers that are also sent.
>
[snip]

I stopped sending Set-Cookie headers... It became too confusing.  I 
found that Javascript worked 99% of the time on every browser and 
operating system with the exception of Lynx...  But if you're using 
cookies anyway, you probably developing for the more common NS and IE 
users.

Good luck,

Rob



--
As soon as you make something foolproof, someone will create a better fool.

Re: forbidden vs. cookie

Posted by Issac Goldstand <ne...@writeme.com>.
I did this in a module of mine.  I simply did a new Apache::Cookie and
 $cookie->bake() followed by
 $r->header_out("Location"=>"http://go.here/now");
 return HTTP_MOVED_TEMPORARILY;

I chose TEMP_REDIRECT as I think it's befitting as the above is (also) from
an AuthenHandler and therefore constitute a problem that's not based on the
content of that specific URI...

Anyway, hope this helps.

   Issac

----- Original Message -----
From: "will trillich" <wi...@serensoft.com>
To: <mo...@apache.org>
Sent: Monday, April 30, 2001 9:31 PM
Subject: forbidden vs. cookie


> i could really use some dumbed-down tips on setting cookies
> during a redirect. boy, this is really getting to me.
>
> using apache 1.3.9 on debian 2.2/potato
>
> in trying to implement the concept of the Apache::Ticket*.pm
> modules from the Apache Modules (eagle) book in chapter 6
> (on pages 304+) i'm running into browser compatibility problems.
> SOME browsers (differs among platforms, too) see the forbidden or
> redirect codes and take action immediately, ignoring any
> set-cookie headers that are also sent.
>
> as a workaround, i was trying to change TicketAccess.pm to
>
> # the munged version trying to accomodate rude browsers:
> package Apache::TicketAccess;
>
> use strict;
> use Apache::Constants qw(OK FORBIDDEN REDIRECT);
> use Apache::TicketTool ();
>
> sub handler {
> my $r = shift;
> my $ticketTool = Apache::TicketTool->new($r);
> my($result, $msg) = $ticketTool->verify_ticket($r);
> unless ($result) {
> $r->log_reason($msg, $r->filename);
> my $cookie = $ticketTool->make_return_address($r);
>
> #the original code that works for SOME browsers:
> # $r->err_headers_out->add('Set-Cookie' => $cookie);
> # return FORBIDDEN;
>
> my $login_uri = $r->dir_config("TicketLogin");
>
> # as AccessHandler, this was very much a bad idea:
> # use CGI '-autoload';
> # print
> # header(-refresh => "1; URL=$login_uri", -cookie => $cookie),
> # start_html(-title => 'Redirecting to login', -bgcolor => 'white'),
> # h1('Gotta log in, first'),
> # p("You're being redirected to ",
> # a({-href=>$login_uri},$login_uri),
> # " in just a moment."),
> # h2("Please stand by..."),
> # end_html();
> # return OK;
> # it does manage to redirect the browser but there's lots
> # of duplicated headers and garbage (plus just hitting the
> # BACK button bypassed the need to log in)
>
> # this don't work so not, neither:
> $r->header_out(-cookie=>$cookie);
> $r->header_out(-location=>$login_uri);
> return REDIRECT;
> # neither header is sent.
>
> }
> return OK;
> }
>
> 1;
> __END__
>
> i've spent hours flipping back and from from the index to the
> text, slapping postit notes on every other page, scanning
> Apache::*.pm source code -- and it's still not sinking in... a
> little help would be appreciated!
>
> AAUGH!
>
> --
> will@serensoft.com
>


Re: forbidden vs. cookie

Posted by Stephen Reppucci <sg...@logsoft.com>.
Howdy Ken!

I think there are two separate issues here -- there's an expiration
time on the cookie, which is your app's instruction to the client as
to how long the cookie should be kept.  Then there's an expiration
time of the ticket represented by that cookie data (to use the
Ticket Auth example), which is the length of time the ticket is
valid for.

The ticket expiration time should be in a (tamper-proof) container
encoded within the cookie, and checked by the server side app for
freshness with each request.

Allowing a client's broken idea of the current time (whether broken
through maliciousness or through ignorance) to affect the duration
of the ticket's validity is (IMO) "a bad thing".

If the client's broken idea of the time causes the cookie not to be
stored for the correct duration, oh well, that's *their* problem,
right?

As Tom Christiansen likes to preach "Never trust anything sent from
the client".

<Steve>

On Tue, 1 May 2001, Ken Y. Clark wrote:

> On Mon, 30 Apr 2001, will trillich wrote:
> > after seeing the 'expires' dilemma brought about by poorly
> > configured client system clocks, what advice should we follow?
> > (what's the Official Party Line on expiring cookies?)
>
> I'm not really sure how to answer your question.  I have usually
> understood that the client handles all of this.  That is, you tell the
> client that the cookie is good for 30 minutes, and it figures out when
> those 30 minutes have expired and then quits sending a valid cookie back
> to the server.  Is that right?  Anyone?  Anyone?  Bueller?


-- 
Steve Reppucci                                       sgr@logsoft.com |
Logical Choice Software                          http://logsoft.com/ |
=-=-=-=-=-=-=-=-=-=-  My God!  What have I done?  -=-=-=-=-=-=-=-=-=-=



Re: forbidden vs. cookie

Posted by "Ken Y. Clark" <kc...@logsoft.com>.
On Mon, 30 Apr 2001, will trillich wrote:

> Date: Mon, 30 Apr 2001 18:17:11 -0500
> From: will trillich <wi...@serensoft.com>
> To: modperl@apache.org
> Subject: Re: forbidden vs. cookie
>
> On Mon, Apr 30, 2001 at 03:46:17PM -0400, Ken Y. Clark wrote:
> > Here is some code I've used in the past in a mod_perl app to
> > set a cookie and do a redirect at the same time.  I believe it
> > works for most browsers -- or at least this code has been
> > working for over a year and I haven't heard too many complaints
> > about this piece (that I can think of).
> >
> > my $cookie = Apache::Cookie->new($apr,
> >                  -name    => 'foo',
> >                  -value   => 'bar',
> >                  -expires => '+30m',
> >                  -domain  => '.domain.com',
> >                  -path    => '/',
> >             );
> > $cookie->bake;
> >
> > $apr->method_number(M_GET);
> > $apr->method('GET');
> > $apr->headers_in->unset('Content-length');
> > $apr->headers_out->add('Location' => '/foo');
> > $apr->status(REDIRECT);
> > $apr->send_http_header;
> > return OK;
>
> i presume $apr is as in "sub handler { my $apr = shift; ... " ?

Yes.  I'm sorry, I should have been more explicit.  Actually, the
first line of the handler() is this:

my $apr = Apache::Request->new( shift() );

> and is this in PerlAuthhandler?

No, I used this in a PerlHandler as the <Location> for logging a user
into the mp3.boston.com site.  Again, I believe my method works --
though I never tested it exhaustively in every conceivable browser.  I
simply made sure it worked on the major browsers (Netscape and IE) on
Linux, Solaris, Mac and Windows.  I wanted to do exactly what you
want:  Set a cookie (mine being the "logged in" information) and
simulaneously redirect the user to their "home" page on the site.

I do, however, use a PerlAccessHandler like so:

    <Location /upload>
        PerlAccessHandler BGEP::MP3::VerifyLogin
        ErrorDocument     403 http://mp3.boston.com/login/login.shtml
    </Location>

It checks every request for a valid "session" cookie (which contains
nothing more than the user's id and will fail to be returned when the
cookie expires).

> after seeing the 'expires' dilemma brought about by poorly
> configured client system clocks, what advice should we follow?
> (what's the Official Party Line on expiring cookies?)

I'm not really sure how to answer your question.  I have usually
understood that the client handles all of this.  That is, you tell the
client that the cookie is good for 30 minutes, and it figures out when
those 30 minutes have expired and then quits sending a valid cookie back
to the server.  Is that right?  Anyone?  Anyone?  Bueller?

ky


Re: forbidden vs. cookie

Posted by will trillich <wi...@serensoft.com>.
On Mon, Apr 30, 2001 at 03:46:17PM -0400, Ken Y. Clark wrote:
> Here is some code I've used in the past in a mod_perl app to
> set a cookie and do a redirect at the same time.  I believe it
> works for most browsers -- or at least this code has been
> working for over a year and I haven't heard too many complaints
> about this piece (that I can think of).
> 
> my $cookie = Apache::Cookie->new($apr,
>                  -name    => 'foo',
>                  -value   => 'bar',
>                  -expires => '+30m',
>                  -domain  => '.domain.com',
>                  -path    => '/',
>             );
> $cookie->bake;
> 
> $apr->method_number(M_GET);
> $apr->method('GET');
> $apr->headers_in->unset('Content-length');
> $apr->headers_out->add('Location' => '/foo');
> $apr->status(REDIRECT);
> $apr->send_http_header;
> return OK;

i presume $apr is as in "sub handler { my $apr = shift; ... " ?

and is this in PerlAuthhandler?

after seeing the 'expires' dilemma brought about by poorly
configured client system clocks, what advice should we follow?
(what's the Official Party Line on expiring cookies?)

-- 
will@serensoft.com

Re: forbidden vs. cookie

Posted by "Ken Y. Clark" <kc...@logsoft.com>.
On Mon, 30 Apr 2001, will trillich wrote:

> Date: Mon, 30 Apr 2001 14:31:02 -0500
> From: will trillich <wi...@serensoft.com>
> To: modperl@apache.org
> Subject: forbidden vs. cookie
>
> i could really use some dumbed-down tips on setting cookies
> during a redirect. boy, this is really getting to me.
>
> using apache 1.3.9 on debian 2.2/potato
>
> in trying to implement the concept of the Apache::Ticket*.pm
> modules from the Apache Modules (eagle) book in chapter 6
> (on pages 304+) i'm running into browser compatibility problems.
> SOME browsers (differs among platforms, too) see the forbidden or
> redirect codes and take action immediately, ignoring any
> set-cookie headers that are also sent.
>
> as a workaround, i was trying to change TicketAccess.pm to
>
> 	# the munged version trying to accomodate rude browsers:
> 	package Apache::TicketAccess;
>
> 	use strict;
> 	use Apache::Constants qw(OK FORBIDDEN REDIRECT);
> 	use Apache::TicketTool ();
>
> 	sub handler {
> 		my $r = shift;
> 		my $ticketTool = Apache::TicketTool->new($r);
> 		my($result, $msg) = $ticketTool->verify_ticket($r);
> 		unless ($result) {
> 			$r->log_reason($msg, $r->filename);
> 			my $cookie = $ticketTool->make_return_address($r);
>
> 	#the original code that works for SOME browsers:
> 	#		$r->err_headers_out->add('Set-Cookie' => $cookie);
> 	#		return FORBIDDEN;
>
> 			my $login_uri = $r->dir_config("TicketLogin");
>
> 	# as AccessHandler, this was very much a bad idea:
> 	#		use CGI '-autoload';
> 	#		print
> 	#			header(-refresh => "1; URL=$login_uri", -cookie => $cookie),
> 	#			start_html(-title => 'Redirecting to login', -bgcolor => 'white'),
> 	#			h1('Gotta log in, first'),
> 	#			p("You're being redirected to ",
> 	#				a({-href=>$login_uri},$login_uri),
> 	#				" in just a moment."),
> 	#			h2("Please stand by..."),
> 	#			end_html();
> 	#		return OK;
> 	# it does manage to redirect the browser but there's lots
> 	# of duplicated headers and garbage (plus just hitting the
> 	# BACK button bypassed the need to log in)
>
> 	# this don't work so not, neither:
> 			$r->header_out(-cookie=>$cookie);
> 			$r->header_out(-location=>$login_uri);
> 			return REDIRECT;
> 	# neither header is sent.
>
> 		}
> 		return OK;
> 	}
>
> 	1;
> 	__END__
>
> i've spent hours flipping back and from from the index to the
> text, slapping postit notes on every other page, scanning
> Apache::*.pm source code -- and it's still not sinking in... a
> little help would be appreciated!
>
> AAUGH!

Will,

Here is some code I've used in the past in a mod_perl app to set a
cookie and do a redirect at the same time.  I believe it works for
most browsers -- or at least this code has been working for over a
year and I haven't heard too many complaints about this piece (that I
can think of).

my $cookie = Apache::Cookie->new($apr,
                 -name    => 'foo',
                 -value   => 'bar',
                 -expires => '+30m',
                 -domain  => '.domain.com',
                 -path    => '/',
            );
$cookie->bake;

$apr->method_number(M_GET);
$apr->method('GET');
$apr->headers_in->unset('Content-length');
$apr->headers_out->add('Location' => '/foo');
$apr->status(REDIRECT);
$apr->send_http_header;
return OK;

HTH,

ky