Re: [web2py] Re: login by ajax
Hi! It seems, that ajax_login isn't exist yet? if not user: self.log_event(self.messages['login_failed_log'], request.post_vars) # invalid login session.flash = self.messages.invalid_login callback(onfail, None) redirect( self.url(args=request.args, vars=request.get_vars), client_side=settings.client_side) On Saturday, March 2, 2013 at 5:46:53 PM UTC+3, Phyo Arkar wrote: > > If you worry about your credentials visibility over the wire , SSL. > If you worry about your credentials visibility on the screen , None > actually. > > On Sat, Mar 2, 2013 at 5:54 AM, Alan Etkin> wrote: > >> +1 for auth,ajax_login() >> >> >> I'm also interested in a bare ajax login feature, but, what about the >> security risks of passing credentials with javascript in the background? >> What are the issues to take in account for that feature? I there any >> standard way of securing the passwords and other sensible data that can be >> used? >> >> -- >> >> --- >> You received this message because you are subscribed to the Google Groups >> "web2py-users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to web2py+un...@googlegroups.com . >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >> > > -- Resources: - http://web2py.com - http://web2py.com/book (Documentation) - http://github.com/web2py/web2py (Source code) - https://code.google.com/p/web2py/issues/list (Report Issues) --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[web2py] Re: login by ajax
The data is transmitted on the wire in the same exact manner via an ajax POST or the usual POST. The only security needed is SSL, for both, if you don't want to pass credentials in clear format. On Saturday, March 2, 2013 12:24:44 AM UTC+1, Alan Etkin wrote: +1 for auth,ajax_login() I'm also interested in a bare ajax login feature, but, what about the security risks of passing credentials with javascript in the background? What are the issues to take in account for that feature? I there any standard way of securing the passwords and other sensible data that can be used? -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [web2py] Re: login by ajax
If you worry about your credentials visibility over the wire , SSL. If you worry about your credentials visibility on the screen , None actually. On Sat, Mar 2, 2013 at 5:54 AM, Alan Etkin spame...@gmail.com wrote: +1 for auth,ajax_login() I'm also interested in a bare ajax login feature, but, what about the security risks of passing credentials with javascript in the background? What are the issues to take in account for that feature? I there any standard way of securing the passwords and other sensible data that can be used? -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
sorry for delay: !-- Modal -- div id=Modallogin class=modal hide fade tabindex=-1 role=dialog aria-labelledby=myModalLabel aria-hidden=true div class=modal-header button type=button class=close data-dismiss=modal aria-hidden=trueĆ/button h3 id=myModalLabelLog in /h3 /div div class=modal-body pYou could login by your yahoo or gmail account. /p div id='login_result'/div {{=form}} /div /div script function login_process(user_type){ $('#Modallogin').modal('show'); $('#auth_user_type').val(user_type); } function login(){ var data = $('form').serialize(); $('form input').each(function(){$(this).attr('disabled',true);}); $('#login_result').removeClass('alert alert-error').text(''); $('#login_result').addClass('alert alert-info').text('Connecting...'); $.ajax({ type: POST, url: '{{=URL('default','index')}}', data: data, success : function(response){ $('form input').each(function(){$(this).attr('disabled',false);}); try{ response = jQuery.parseJSON(response); } catch(e){ var response = {'msg':'failed to proceed'}; } if (!response.logged){ $('#login_result').removeClass('alert alert-info').addClass('alert alert-error').text(response.msg); }else{ window.location=response.redirect; } } }); return false; } /script On Thursday, February 28, 2013 4:15:50 AM UTC+3:30, Massimo Di Pierro wrote: I still do not understand. Why index() is under returning some times json and some times dict with a form? Who makes the ajax callback? If this to be embedded in a large page? What is the JS? On Wednesday, 27 February 2013 14:49:04 UTC-6, yashar wrote: def ajax_login_bare(self, username, password): check user login and return tuple of (boolean,msg) which first field is successfull login or not and second is failure massage request = current.request session = current.session table_user = self.settings.table_user if self.settings.login_userfield: userfield = self.settings.login_userfield elif 'username' in table_user.fields: userfield = 'username' else: userfield = 'email' passfield = self.settings.password_field key = {userfield:username,passfield:password} user = self.db(table_user[userfield] == username).select().first() if user: # user in db, check if registration pending or disabled temp_user = user if temp_user.registration_key == 'pending': return (False,self.messages.registration_pending) elif temp_user.registration_key in ('disabled', 'blocked'): return (False,self.messages.login_disabled) elif not temp_user.registration_key is None and temp_user.registration_key.strip(): return (False,self.messages.registration_verifying) # try alternate logins 1st as these have the # current version of the password user = None for login_method in self.settings.login_methods: if login_method != self and login_method(username,password): if not self in self.settings.login_methods: # do not store password in db password = None user = self.get_or_create_user(key) break if not user: # alternates have failed, maybe because service inaccessible if self.settings.login_methods[0] == self: # try logging in locally using cached credentials if password == temp_user[passfield]: # success user = temp_user else: # user not in db if not self.settings.alternate_requires_registration: # we're allowed to auto-register users from external systems for login_method in self.settings.login_methods: if login_method != self and login_method(username,password): if not self in self.settings.login_methods: # do not store password in db key[passfield] = None user = self.get_or_create_user(key) break if not user: self.log_event(self.messages.login_failed_log,request.post_vars) return (False,self.messages.invalid_login) else: user = Row(table_user._filter_fields(user, id=True)) # process authenticated users # user wants to be logged in for longer self.login_user(user) session.auth.expiration = \ request.vars.get('remember', False) and \
[web2py] Re: login by ajax
+1 for auth,ajax_login() I'm also interested in a bare ajax login feature, but, what about the security risks of passing credentials with javascript in the background? What are the issues to take in account for that feature? I there any standard way of securing the passwords and other sensible data that can be used? -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
Can you show an example of how to use it. I see it is not an action. On Wednesday, 20 February 2013 08:00:50 UTC-6, yashar wrote: this is what i added in tools.py inside auth class, this is just modification of login() function and difference from main login_bare is this one also check, creates and logs in users which authenticated with other authentication methods. def ajax_login_bare(self, username, password): check user login and return tuple of (boolean,msg) which first field is successfull login or not and second is failure massage request = current.request session = current.session table_user = self.settings.table_user if self.settings.login_userfield: userfield = self.settings.login_userfield elif 'username' in table_user.fields: userfield = 'username' else: userfield = 'email' passfield = self.settings.password_field key = {userfield:request.vars[userfield],passfield:request.vars[passfield]} user = self.db(table_user[userfield] == request.vars[userfield]).select().first() if user: # user in db, check if registration pending or disabled temp_user = user if temp_user.registration_key == 'pending': return (False,self.messages.registration_pending) elif temp_user.registration_key in ('disabled', 'blocked'): return (False,self.messages.login_disabled) elif not temp_user.registration_key is None and temp_user.registration_key.strip(): return (False,self.messages.registration_verifying) # try alternate logins 1st as these have the # current version of the password user = None for login_method in self.settings.login_methods: if login_method != self and login_method(request.vars[userfield],request.vars[passfield]): if not self in self.settings.login_methods: # do not store password in db request.vars[passfield] = None user = self.get_or_create_user(key) break if not user: # alternates have failed, maybe because service inaccessible if self.settings.login_methods[0] == self: # try logging in locally using cached credentials if request.vars.get(passfield, '') == temp_user[passfield]: # success user = temp_user else: # user not in db if not self.settings.alternate_requires_registration: # we're allowed to auto-register users from external systems for login_method in self.settings.login_methods: if login_method != self and login_method(request.vars[userfield],request.vars[passfield]): if not self in self.settings.login_methods: # do not store password in db key[passfield] = None user = self.get_or_create_user(key) break if not user: self.log_event(self.messages.login_failed_log,request.post_vars) return (False,self.messages.invalid_login) else: user = Row(table_user._filter_fields(user, id=True)) # process authenticated users # user wants to be logged in for longer self.login_user(user) session.auth.expiration = \ request.vars.get('remember', False) and \ self.settings.long_expiration or \ self.settings.expiration session.auth.remember = 'remember' in request.vars self.log_event(self.messages.login_log, user) return (True,self.messages.logged_in) -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
def ajax_login_bare(self, username, password): check user login and return tuple of (boolean,msg) which first field is successfull login or not and second is failure massage request = current.request session = current.session table_user = self.settings.table_user if self.settings.login_userfield: userfield = self.settings.login_userfield elif 'username' in table_user.fields: userfield = 'username' else: userfield = 'email' passfield = self.settings.password_field key = {userfield:username,passfield:password} user = self.db(table_user[userfield] == username).select().first() if user: # user in db, check if registration pending or disabled temp_user = user if temp_user.registration_key == 'pending': return (False,self.messages.registration_pending) elif temp_user.registration_key in ('disabled', 'blocked'): return (False,self.messages.login_disabled) elif not temp_user.registration_key is None and temp_user.registration_key.strip(): return (False,self.messages.registration_verifying) # try alternate logins 1st as these have the # current version of the password user = None for login_method in self.settings.login_methods: if login_method != self and login_method(username,password): if not self in self.settings.login_methods: # do not store password in db password = None user = self.get_or_create_user(key) break if not user: # alternates have failed, maybe because service inaccessible if self.settings.login_methods[0] == self: # try logging in locally using cached credentials if password == temp_user[passfield]: # success user = temp_user else: # user not in db if not self.settings.alternate_requires_registration: # we're allowed to auto-register users from external systems for login_method in self.settings.login_methods: if login_method != self and login_method(username,password): if not self in self.settings.login_methods: # do not store password in db key[passfield] = None user = self.get_or_create_user(key) break if not user: self.log_event(self.messages.login_failed_log,request.post_vars) return (False,self.messages.invalid_login) else: user = Row(table_user._filter_fields(user, id=True)) # process authenticated users # user wants to be logged in for longer self.login_user(user) session.auth.expiration = \ request.vars.get('remember', False) and \ self.settings.long_expiration or \ self.settings.expiration session.auth.remember = 'remember' in request.vars self.log_event(self.messages.login_log, user) return (True,self.messages.logged_in) def index(): if request http://127.0.0.1:8000/examples/global/vars/request.post_vars: from gluon.serializers import json logged,msg = auth.ajax_login_bare(request http://127.0.0.1:8000/examples/global/vars/request.vars.email,request http://127.0.0.1:8000/examples/global/vars/request.vars.password) if logged: return json(dict(redirect http://127.0.0.1:8000/examples/global/vars/redirect=get_user_info(),logged=logged,msg=msg)) else: return json(dict(logged=logged,msg=msg)) form = auth.login() return dict(form=form) -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
I still do not understand. Why index() is under returning some times json and some times dict with a form? Who makes the ajax callback? If this to be embedded in a large page? What is the JS? On Wednesday, 27 February 2013 14:49:04 UTC-6, yashar wrote: def ajax_login_bare(self, username, password): check user login and return tuple of (boolean,msg) which first field is successfull login or not and second is failure massage request = current.request session = current.session table_user = self.settings.table_user if self.settings.login_userfield: userfield = self.settings.login_userfield elif 'username' in table_user.fields: userfield = 'username' else: userfield = 'email' passfield = self.settings.password_field key = {userfield:username,passfield:password} user = self.db(table_user[userfield] == username).select().first() if user: # user in db, check if registration pending or disabled temp_user = user if temp_user.registration_key == 'pending': return (False,self.messages.registration_pending) elif temp_user.registration_key in ('disabled', 'blocked'): return (False,self.messages.login_disabled) elif not temp_user.registration_key is None and temp_user.registration_key.strip(): return (False,self.messages.registration_verifying) # try alternate logins 1st as these have the # current version of the password user = None for login_method in self.settings.login_methods: if login_method != self and login_method(username,password): if not self in self.settings.login_methods: # do not store password in db password = None user = self.get_or_create_user(key) break if not user: # alternates have failed, maybe because service inaccessible if self.settings.login_methods[0] == self: # try logging in locally using cached credentials if password == temp_user[passfield]: # success user = temp_user else: # user not in db if not self.settings.alternate_requires_registration: # we're allowed to auto-register users from external systems for login_method in self.settings.login_methods: if login_method != self and login_method(username,password): if not self in self.settings.login_methods: # do not store password in db key[passfield] = None user = self.get_or_create_user(key) break if not user: self.log_event(self.messages.login_failed_log,request.post_vars) return (False,self.messages.invalid_login) else: user = Row(table_user._filter_fields(user, id=True)) # process authenticated users # user wants to be logged in for longer self.login_user(user) session.auth.expiration = \ request.vars.get('remember', False) and \ self.settings.long_expiration or \ self.settings.expiration session.auth.remember = 'remember' in request.vars self.log_event(self.messages.login_log, user) return (True,self.messages.logged_in) def index(): if request http://127.0.0.1:8000/examples/global/vars/request.post_vars: from gluon.serializers import json logged,msg = auth.ajax_login_bare(request http://127.0.0.1:8000/examples/global/vars/request.vars.email,request http://127.0.0.1:8000/examples/global/vars/request.vars.password) if logged: return json(dict(redirect http://127.0.0.1:8000/examples/global/vars/redirect=get_user_info(),logged=logged,msg=msg)) else: return json(dict(logged=logged,msg=msg)) form = auth.login() return dict(form=form) -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
this is what i added in tools.py inside auth class, this is just modification of login() function and difference from main login_bare is this one also check, creates and logs in users which authenticated with other authentication methods. def ajax_login_bare(self, username, password): check user login and return tuple of (boolean,msg) which first field is successfull login or not and second is failure massage request = current.request session = current.session table_user = self.settings.table_user if self.settings.login_userfield: userfield = self.settings.login_userfield elif 'username' in table_user.fields: userfield = 'username' else: userfield = 'email' passfield = self.settings.password_field key = {userfield:request.vars[userfield],passfield:request.vars[passfield]} user = self.db(table_user[userfield] == request.vars[userfield]).select().first() if user: # user in db, check if registration pending or disabled temp_user = user if temp_user.registration_key == 'pending': return (False,self.messages.registration_pending) elif temp_user.registration_key in ('disabled', 'blocked'): return (False,self.messages.login_disabled) elif not temp_user.registration_key is None and temp_user.registration_key.strip(): return (False,self.messages.registration_verifying) # try alternate logins 1st as these have the # current version of the password user = None for login_method in self.settings.login_methods: if login_method != self and login_method(request.vars[userfield],request.vars[passfield]): if not self in self.settings.login_methods: # do not store password in db request.vars[passfield] = None user = self.get_or_create_user(key) break if not user: # alternates have failed, maybe because service inaccessible if self.settings.login_methods[0] == self: # try logging in locally using cached credentials if request.vars.get(passfield, '') == temp_user[passfield]: # success user = temp_user else: # user not in db if not self.settings.alternate_requires_registration: # we're allowed to auto-register users from external systems for login_method in self.settings.login_methods: if login_method != self and login_method(request.vars[userfield],request.vars[passfield]): if not self in self.settings.login_methods: # do not store password in db key[passfield] = None user = self.get_or_create_user(key) break if not user: self.log_event(self.messages.login_failed_log,request.post_vars) return (False,self.messages.invalid_login) else: user = Row(table_user._filter_fields(user, id=True)) # process authenticated users # user wants to be logged in for longer self.login_user(user) session.auth.expiration = \ request.vars.get('remember', False) and \ self.settings.long_expiration or \ self.settings.expiration session.auth.remember = 'remember' in request.vars self.log_event(self.messages.login_log, user) return (True,self.messages.logged_in) -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
i think login_bare needs to write again, in login() function, it first checks the login_methods and then local database and also create_or_get_user and update session.auth, but in login_bare it just check the database if user is there add it to session but not doing any of the login() steps which brings many problems like if user changed his gmail password. i think login_bare should be just like login() with the difference of instead of returning form it should return messages in pliantext or json. On Monday, February 18, 2013 9:04:48 PM UTC+3:30, Massimo Di Pierro wrote: self.login_bare() calls self.login_user(...) and it automatically logs in the user and stores user in session.auth.user -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
+1 for auth,ajax_login() paolo On Monday, February 18, 2013 4:50:20 AM UTC+1, Massimo Di Pierro wrote: Should we offer something like {{=auth.ajax_login()}} helper which submits to /user/login? If would not be difficult to write. How should it work? On Sunday, 17 February 2013 21:37:59 UTC-6, Anthony wrote: def login(): form=auth.login() if form.accepts(request,session=None): auth.login() already handles form processing, so you should not call form.accepts(), as that will not work. form action='' fieldset div id='login_result'/div labelEmail/label input name='email' id='email' type=text placeholder=Email Address labelPassword/label input name='password' id='password' type=password placeholder=*br/ button id='loginbtn' class=btn Onclick='login();return false;'Submit/button /fieldset /form web2py SQLFORM's (including the auth forms) include hidden _formname and _formkey fields -- if you're creating a custom form, you need to include those, or the form will not pass validation when submitted. If you want to create a custom form based on a SQLFORM, you should follow http://web2py.com/books/default/chapter/29/07#Custom-forms. Also, rather than manually submitting the form via Ajax, you might consider putting the login form in an Ajax component (or even a non-Ajax component with ajax_trap set to True). In that case, web2py.js will handle the Ajax submission for you. In that case, you may want to create a login_onaccept function to avoid the usual post-login redirect (which wouldn't be useful for an Ajax login). Anthony -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
self.login_bare() calls self.login_user(...) and it automatically logs in the user and stores user in session.auth.user On Sunday, 17 February 2013 23:34:01 UTC-6, yashar wrote: is there any way that i log in user by code? for example after checking username and password with login_bare, i push the user into the session as logged-in user? in this case there is no need to write ajax/login directly, and the programmer has a better control.as you can see in my code i check user two times one in bare_login and one in auth.login, because i can not return 'login failed' value from code if i use just form=auth.login(). when the formkey is changing? during form creation or after each submit? because i create two auth.login() forms one in the index for view and one in login function, and this is working so the formkey must be same, but could you help me to write a cleaner code? in that code after success login page automaticly redirected as i dont understand why? -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
def login(): form=auth.login() if form.accepts(request,session=None): auth.login() already handles form processing, so you should not call form.accepts(), as that will not work. form action='' fieldset div id='login_result'/div labelEmail/label input name='email' id='email' type=text placeholder=Email Address labelPassword/label input name='password' id='password' type=password placeholder=*br/ button id='loginbtn' class=btn Onclick='login();return false;'Submit/button /fieldset /form web2py SQLFORM's (including the auth forms) include hidden _formname and _formkey fields -- if you're creating a custom form, you need to include those, or the form will not pass validation when submitted. If you want to create a custom form based on a SQLFORM, you should follow http://web2py.com/books/default/chapter/29/07#Custom-forms. Also, rather than manually submitting the form via Ajax, you might consider putting the login form in an Ajax component (or even a non-Ajax component with ajax_trap set to True). In that case, web2py.js will handle the Ajax submission for you. In that case, you may want to create a login_onaccept function to avoid the usual post-login redirect (which wouldn't be useful for an Ajax login). Anthony -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
Should we offer something like {{=auth.ajax_login()}} helper which submits to /user/login? If would not be difficult to write. How should it work? On Sunday, 17 February 2013 21:37:59 UTC-6, Anthony wrote: def login(): form=auth.login() if form.accepts(request,session=None): auth.login() already handles form processing, so you should not call form.accepts(), as that will not work. form action='' fieldset div id='login_result'/div labelEmail/label input name='email' id='email' type=text placeholder=Email Address labelPassword/label input name='password' id='password' type=password placeholder=*br/ button id='loginbtn' class=btn Onclick='login();return false;'Submit/button /fieldset /form web2py SQLFORM's (including the auth forms) include hidden _formname and _formkey fields -- if you're creating a custom form, you need to include those, or the form will not pass validation when submitted. If you want to create a custom form based on a SQLFORM, you should follow http://web2py.com/books/default/chapter/29/07#Custom-forms. Also, rather than manually submitting the form via Ajax, you might consider putting the login form in an Ajax component (or even a non-Ajax component with ajax_trap set to True). In that case, web2py.js will handle the Ajax submission for you. In that case, you may want to create a login_onaccept function to avoid the usual post-login redirect (which wouldn't be useful for an Ajax login). Anthony -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
thank you, i solve the problem like this: def index(): form = auth.login() form.elements('input',_type='submit')[0]['_Onclick']='login();return false;' return dict(form=form) def login(): if not auth.login_bare(request.vars.email,request.vars.password): return 'login failed' form=auth.login() if auth.user : return 'logged' return dict(form=form) and in the index view: div id='login_result'/div {{=form}} script function login(){ alert('here'); $.ajax({ type: POST, url: '{{=URL('default','login')}}', data: $('form').serialize(), success : function(data){ if (data != 'True'){ $('#login_result').addClass('alert alert-error').text('Email Or password were wrong! Please try again.'); } else { } } }); return false; } /script -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
[web2py] Re: login by ajax
is there any way that i log in user by code? for example after checking username and password with login_bare, i push the user into the session as logged in user? in this case there is no need to write ajax/login directly, and the programmer has a better control. if i write : def login(): -- --- You received this message because you are subscribed to the Google Groups web2py-users group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.