I too, use a heavily modified version of authentication (mostly due to UI and workflow design choices), while =FORM() is incredibly useful for many situations, I don't use it in any of my applications.
I am therefore at the mercy of the internal py4web mechanism to sign up/login, here's my example (edited for simplicity):
### Custom Login
@action('custom_auth/login', method=['get', 'post'])
@action.uses('custom_auth/login.html', auth)
def custom_auth_login():
""" Custom Login Page """
if request.method == 'POST':
email = request.forms.get('email', '')
passwd = request.forms.get('passwd', '')
# internal engine's login
user, error = auth.login(email, passwd)
if user:
auth.store_user_in_session(user['id'])
### Custom Registration
@action('custom_auth/register', method=['get', 'post'])
@action.uses('custom_auth/register.html')
def custom_auth_register():
""" Custom Register Page """
if request.method == 'POST':
email = request.forms.get('email', '')
password = form.get('password', '')
password_again = form.get('password_again', '')
crypt_password = CRYPT()(password)[0]
payload = {
'username': 'testuser',
'email': email,
'password': crypt_password,
'password_again': crypt_password,
'first_name': 'First;,
'last_name': 'Last'
}
# Internal engine's register
registration_results = auth.register(payload, validate=False)
# if 'errors' in registration_results, then handle them
I would like to see an interface that provides these methods "naked", that is, decoupled from FORM() or other elements, maybe the auth REST endpoints could do this, however the above is working perfectly fine for my needs, however, if any of the implementation details in auth.py change, (say, py4web removes or replaces CRYPT(), then the above will need to be revised).
As always thanks Massimo for this awesome framework.