Getting auth.settings.register_next to work...

437 views
Skip to first unread message

Doug Philips

unread,
Jun 30, 2012, 2:37:36 AM6/30/12
to web2py
I've been customizing how registration works for my app as a few of my
app's users are getting confused by the registration verification
email.
Ok, so I will just have my app send them to a nice hand-holding
explanatory page after they've submitted their registration
information.

According to The Book, "all" I have to do is set
auth.settings.register_next to the URL I want, and I'm good to go.
But I can't get that to work.

(all line numbers are for
https://github.com/web2py/web2py/blob/master/gluon/tools.py as of the
time of this message)

First off, it seems that the Register link I get from auth.navbar()
always has a _next parameter appended to it,
and that _next seems to override anything I set in my model for
auth.settings.registration_next.
Fine, I go into the navbar function of the Auth class in tools.py and
delete the "+next" part of the registration link. (line 1242)
That doesn't work, as for some reason I don't understand, the ?_next
parameter in the URL is still present when the navbar is constructed
from a regular page, but the ?_next parameter is (properly) missing
from Register link when I first click on Login. Very odd to me.

After trying a few more fixes, I decide that I do not understand how
next processing is done for Auth.
My fix is a huge hammer.
I go into the register function and change lines 1983 and 1984.
Actually I delete them and replace them with:
next = self.settings.register_next

I have no idea what the lines I deleted are trying to do, but they
were keeping my expressed intent from working.
Now my users are directed to the page I want after submitting their
registrations, but I have no idea what else I have subtly screwed up.
I don't even know if I should submit a bug report or if there is some
other configuration I could do that would avoid having to make this
code change.
Help!

-Doug

Doug Philips

unread,
Jun 30, 2012, 2:41:28 AM6/30/12
to web2py
On Sat, Jun 30, 2012 at 2:37 AM, I wrote:
> and that _next seems to override anything I set in my model for
> auth.settings.registration_next.

Typo, I should have written:
and that _next parameter seems to override anything I set in my model
for auth.settings.register_next

-=D

Anthony

unread,
Jun 30, 2012, 10:12:50 AM6/30/12
to web...@googlegroups.com
Looks like auth.navbar() automatically adds the current URL as the _next parameter so whenever someone clicks on an auth.navbar() link, after finishing that action, they are returned to their original page. Also, auth.settings.register_next (and similar) are only used as backup defaults when there is no _next parameter in the URL (i.e., _next takes precedence). Perhaps we should make it easier to override these two behaviors. For now, though, I think you have a few options.

First, right after you define auth, do:

auth = Auth(...)
auth
.next = None

That should remove the _next value, which will allow the auth.settings.register_next setting to take effect. Alternatively, right before you define auth, you can remove _next from request.vars:

request.vars._next = None
auth
= Auth(...)

You can also pass a "next" argument directly to the auth.register() function (and other Auth functions):

def user():
   
if request.args(0) == 'register':
        form
= auth.register(next=auth.settings.register_next)
   
else:
        form
= auth()
   
return dict(form=form)

Anthony

Anthony

unread,
Jun 30, 2012, 10:13:53 AM6/30/12
to web...@googlegroups.com
Note, the first two options below will disable the _next functionality for all Auth actions. The last solution disables it only for the register action.

Anthony

Doug Philips

unread,
Jun 30, 2012, 10:29:47 AM6/30/12
to web...@googlegroups.com
Looking at tools/gluon.py again now that I have something working and
I am not in a rush, I notice something curious, lines 1226 and 1227:

li_next = '?_next='+urllib.quote(self.settings.login_next)
lo_next = '?_next='+urllib.quote(self.settings.logout_next)

So it looks as if maybe a 'more correct'? :-) solution might be to do
something similar with register_next being used to create the "_next"
parameter?

Nonetheless, how Auth implements where to go next just seems
excessively tangled. There are next parameters to the methods, next
parameters in the URLs, and finally, auth.settings.<something>_next
fields which are of the last resort, and it is hard to see under what
circumstances the auth.settings.<something>_next fields will ever get
used (except for login_next and logout_next, as per the code quoted
above). It would be nice to understand what the use case(s) are for
all these next 'control points'...

At this point I still don't think I understand what's going on well
enough to submit a coherent bug report (I like to submit proposed
fixes too, but I'm not even close to thinking I can do that here).

Thanks for the help,
-Doug

Anthony

unread,
Jun 30, 2012, 11:11:24 AM6/30/12
to web...@googlegroups.com
Nonetheless,  how Auth implements where to go next just seems
excessively tangled. There are next parameters to the methods, next
parameters in the URLs, and finally, auth.settings.<something>_next
fields which are of the last resort, and it is hard to see under what
circumstances the auth.settings.<something>_next fields will ever get
used (except for login_next and logout_next, as per the code quoted
above). It would be nice to understand what the use case(s) are for
all these next 'control points'...

Yes, I agree. 

At this point I still don't think I understand what's going on well
enough to submit a coherent bug report (I like to submit proposed
fixes too, but I'm not even close to thinking I can do that here).

I don't think it's a bug, per se, but the behavior (and documentation) could be improved.

Anthony

Doug Philips

unread,
Jul 1, 2012, 9:49:44 PM7/1/12
to web...@googlegroups.com
On Sat, Jun 30, 2012 at 11:11 AM, Anthony <abas...@gmail.com> wrote:
> I don't think it's a bug, per se, but the behavior (and documentation) could
> be improved.

??? The documentation is quite direct and clear that you can set
auth.settings.register_next to control where the user goes next. It
doesn't work. It's not even clear that it can work given the current
code base. I've just created a bug report for it
http://code.google.com/p/web2py/issues/detail?id=869.

login_next and register_next are mentioned exactly once in the
documentation and there is no indication why login_next should work,
but register_next not.

Thanks,
-Doug

Anthony

unread,
Jul 2, 2012, 1:03:25 AM7/2/12
to web...@googlegroups.com
> I don't think it's a bug, per se, but the behavior (and documentation) could
> be improved.

??? The documentation is quite direct and clear that you can set
auth.settings.register_next to control where the user goes next. It
doesn't work. It's not even clear that it can work given the current
code base.

Here's what the book says:

These must point to the URL you want to redirect your users to after the various possible auth actions (in case there is no referrer):

Notice the highlighted text. The _next URLs are default redirect URLs when there is no referring page, and auth.settings.register_next does in fact work when there is no referring page (i.e., when there is no _next var in the URL). The issue is not with auth.settings.register_next, but with the auth.navbar() helper. The navbar helper always adds the current page URL as the _next var in the register link, so if you use the navbar to get to the registration page, you will be redirected back to the page from which you clicked the link.

Note, you do not have to use the navbar to generate your Auth links. If you do want to use it, there is an easy workaround. If you don't want to have to use a workaround, then as I suggested, perhaps we can improve the navbar by enabling some redirect options. But I still don't see a bug with auth.settings.register_next. The intended behavior is that a referrer takes precedence, and auth.settings.register_next is the default when there is no referrer -- and that's how it works. We now just need an easy way to prevent the navbar from automatically adding a referrer.

Anthony

Doug Philips

unread,
Jul 2, 2012, 10:16:06 AM7/2/12
to web...@googlegroups.com
On Mon, Jul 2, 2012 at 1:03 AM, Anthony <abas...@gmail.com> wrote:
> Here's what the book says:
> These must point to the URL you want to redirect your users to after the
> various possible auth actions (in case there is no referrer):
>
> Notice the highlighted text. The _next URLs are default redirect URLs when
> there is no referring page, and auth.settings.register_next does in fact
> work when there is no referring page (i.e., when there is no _next var in
> the URL).

I searched the book (free PDF) for "referrer".
The term "referrer" only occurs once, where you quoted above. No
explanation given, no mention of a "_next" var in the URL.
Then I searched for "referer" thinking, OK, maybe the explanation I'm
looking for just has a typo, but found only an example of
request.env.http_referer... Maybe if I search for "_next" I'll find
some explanation that doesn't use 'referrer' but a similar term... the
only other use of "_next" is on page 346 (free PDF) where _next fields
are described as "the URL to redirect to after a successful
<operation> record." THAT'S WHAT I WANT, YAY! Woo! Hoo! No? Oh well.
It would be really nice if things with similar names had similar
meanings...


> The issue is not with auth.settings.register_next, but with the
> auth.navbar() helper. The navbar helper always adds the current page URL as
> the _next var in the register link, so if you use the navbar to get to the
> registration page, you will be redirected back to the page from which you
> clicked the link.

Unless of course you set auth.settings.login_next, in which case, no,
it doesn't; the automatically generated auth links use
auth.settings.login_next and not the page from which I clicked the
link.


> But I still don't see a bug with auth.settings.register_next.

I don't really care if the cause of the bug is the navbar function or
something else. Since auth.settings.register_next is a passive
variable, of course that can't BE the bug.

I'm trying to report what, as a mere user and not implementor, is an
anomalous behavior.
Setting auth.settings.login_next "does the right thing" (the
automatically generated navigation bar), setting
auth.settings.register_next does not have that same behavior. Maybe
that one is "has a bug." Of course since that one does what I
want/expect (see above), then from my point of view as a user of
web2py and not an implementor, it is auth.setting.register_next which
has the bug.


> The intended behavior is that a referrer takes
> precedence, and auth.settings.register_next is the default when there is no
> referrer -- and that's how it works. We now just need an easy way to prevent
> the navbar from automatically adding a referrer.

And to make it treat all the auth.settings' _next fields uniformly (or
document why it shouldn't).
Oh, and to document what "referrer" means in this context. I'll go add
a bug report for that when I've sent this.

Thanks,
-Doug

Anthony

unread,
Jul 2, 2012, 11:03:58 AM7/2/12
to web...@googlegroups.com
I searched the book (free PDF) for "referrer".
The term "referrer" only occurs once, where you quoted above. No
explanation given, no mention of a "_next" var in the URL.
Then I searched for "referer" thinking, OK, maybe the explanation I'm
looking for just has a typo, but found only an example of
request.env.http_referer... Maybe if I search for "_next" I'll find
some explanation that doesn't use 'referrer' but a similar term... 

As I said, I believe the documentation needs improvement here. It appears the navbar _next parameter isn't documented in the book yet (was probably added sometime after the last book revision). We should also add an option to the navbar helper allowing you to disable the _next behavior for particular actions. I'm not sure what else you want.

the 
only other use of "_next" is on page 346 (free PDF) where _next fields 
are described as "the URL to redirect to after a successful 
<operation> record." THAT'S WHAT I WANT, YAY! Woo! Hoo! No? Oh well. 
It would be really nice if things with similar names had similar 
meanings...

Seems to me this has precisely the same meaning (though in a different context). In the context of Auth, register_next is the URL after you register, and in the context of Crud, create_next is the URL after submission of a create form. What's the problem? 
 
> The issue is not with auth.settings.register_next, but with the
> auth.navbar() helper. The navbar helper always adds the current page URL as
> the _next var in the register link, so if you use the navbar to get to the
> registration page, you will be redirected back to the page from which you
> clicked the link.

Unless of course you set auth.settings.login_next, in which case, no,
it doesn't; the automatically generated auth links use
auth.settings.login_next and not the page from which I clicked the
link.

I believe I only mentioned the register link, so not sure what you're disagreeing with here. Yes, though, it does appear that the navbar does not do the same thing with the login link, and I'm not quite sure why -- I think it probably should (and I mentioned that in my comment on the Google Code issue).
 
> But I still don't see a bug with auth.settings.register_next.

I don't really care if the cause of the bug is the navbar function or
something else. Since auth.settings.register_next is a passive
variable, of course that can't BE the bug.

Of course. But you implied there was a bug in the way auth.settings.register_next was being handled in the register() function (i.e., that it is always ignored, which is not the case). It is in fact being handled as intended. Moreover, your suggested fix (to have auth.settings.register_next take precedence within the register() function) would actually break the intended behavior. It's important to identify the real problem before attempting a fix.
 
> The intended behavior is that a referrer takes
> precedence, and auth.settings.register_next is the default when there is no
> referrer -- and that's how it works. We now just need an easy way to prevent
> the navbar from automatically adding a referrer.

And to make it treat all the auth.settings' _next fields uniformly (or
document why it shouldn't).

I agree, though probably not for logout, as the current page may no longer be accessible after logout.

Anthony

Doug Philips

unread,
Jul 2, 2012, 2:22:55 PM7/2/12
to web...@googlegroups.com
On Mon, Jul 2, 2012 at 11:03 AM, Anthony <abas...@gmail.com> wrote:
> Seems to me this has precisely the same meaning (though in a different
> context). In the context of Auth, register_next is the URL after you
> register, and in the context of Crud, create_next is the URL after
> submission of a create form. What's the problem?

By "precisely the same meaning", do you mean that there is a _next URL
parameter that can override the Crud create_next (and others) field
settings and it is a bug that The Book doesn't say so?

...

> Moreover, your suggested fix (to have
> auth.settings.register_next take precedence within the register() function)
> would actually break the intended behavior. It's important to identify the
> real problem before attempting a fix.

Since you wrote: "it does appear that the navbar does not do the same
thing with the login link, and I'm not quite sure why" I don't have
much confidence in your claim to knowing what the intended behavior
is. As I wrote in my first message:
"...I have no idea what else I have subtly screwed up. I don't even
know if I should submit a bug report or if there is some other
configuration I could do that would avoid having to make this code
change."

Having spent hours reading through the book and then the code to see
what mistake I had made configuring auth.settings and/or my app in
general, I finally had to give up and just use my big hammer solution
so that I could move on to doing more substantial work on my app. No
one has explained why login_next is different nor how it fits into
some notion of what the current design/intent is. I deeply regret that
I did anything other than file a bug report, in total:
"auth.setting.login_next and auth.settings.register_next are
documented to behave the same, but do not." I esp. regret all the
investigative work and time I spent on my first message of this
thread.

-=Doug

Anthony

unread,
Jul 2, 2012, 6:08:59 PM7/2/12
to web...@googlegroups.com
> Seems to me this has precisely the same meaning (though in a different
> context). In the context of Auth, register_next is the URL after you
> register, and in the context of Crud, create_next is the URL after
> submission of a create form. What's the problem?

By "precisely the same meaning", do you mean that there is a _next URL
parameter that can override the Crud create_next (and others) field
settings and it is a bug that The Book doesn't say so?

No, I do not mean that. Referencing crud.settings.create_next in the context of discussing auth.settings.register_next, you lamented that you wished things with the same name had the same meaning. I believe these do. There is no _next URL parameter for Crud, as it would not make sense in that context. Are you suggesting Crud shouldn't use the "create_next" terminology merely because Crud doesn't also have a _next URL variable parallel to that of the Auth system? In that case, how exactly do you suggest changing the API?
 
> Moreover, your suggested fix (to have
> auth.settings.register_next take precedence within the register() function)
> would actually break the intended behavior. It's important to identify the
> real problem before attempting a fix.

Since you wrote: "it does appear that the navbar does not do the same
thing with the login link, and I'm not quite sure why" I don't have
much confidence in your claim to knowing what the intended behavior
is.

Note, the code explicitly creates a separate _next link for login (and logout): http://code.google.com/p/web2py/source/browse/gluon/tools.py#1226, but does not do so for register or the other actions, so I think it is safe to assume the intention was for these to behave differently. Furthermore, every place next is defined, it gives precedence to the _next URL parameter over the auth.settings.<action>_next setting (e.g., http://code.google.com/p/web2py/source/browse/gluon/tools.py#1984). Finally, as has been pointed out, the book itself says the auth.settings are there for cases where there is no referrer. To me, this makes sense (use the referrer when present; fall back to the fixed setting otherwise). I therefore infer that the behavior is as intended. If you disagree, please explain.
 
 As I wrote in my first message:
"...I have no idea what else I have subtly screwed up. I don't even
know if I should submit a bug report or if there is some other
configuration I could do that would avoid having to make this code
change."

I'm not sure why you are so concerned. In my original reply, I explained clearly what is going on and how you can implement an easy workaround, pending a new option being added to the navbar helper. 

Having spent hours reading through the book and then the code to see
what mistake I had made configuring auth.settings and/or my app in
general, I finally had to give up and just use my big hammer solution
so that I could move on to doing more substantial work on my app.

What's wrong with the much smaller hammer solution I provided?
 
No
one has explained why login_next is different nor how it fits into
some notion of what the current design/intent is.

login_next works the same as register_next. The difference is in how the navbar generates the login link versus the register link. I agree it's not clear why the login link is treated differently, and I think it should perhaps be changed (though I think it is appropriate to treat the logout link differently). Nevertheless, I don't think this is something to get overly worked up about.

Anthony

Anthony

unread,
Jul 8, 2012, 10:28:45 PM7/8/12
to web...@googlegroups.com
For those interested, in trunk, auth.navbar() now takes a referrer_actions argument. If you do:

auth.navbar(referrer_actions=None)

It will no longer add referrer URLs to the query strings of any of the navbar links, so any auth.settings.<action>_next settings will take precedence in that case. If you want referrer URLs for some but not all of the actions, you can add them to a list:

auth.navbar(referrer_actions=['login', 'profile'])

Note, by default, all links (except logout) still get referrer URLs in the query string, which is unchanged from the original behavior -- so if you want the original behavior, you don't have to do anything different (i.e., this is backward compatible).

Anthony

On Saturday, June 30, 2012 10:12:50 AM UTC-4, Anthony wrote:
Reply all
Reply to author
Forward
0 new messages