If you benefit from web2py hope you feel encouraged to pay it forward by contributing back to society in whatever form you choose!

There is already a good rpxauth module for web2py in existence but I needed to be able to have local accounts in conjunction with the RPX providers. This is what I came up with.

Download the module here and put it in your application's modules folder.

Go to rpxnow.com, sign up then configure your providers.

Instantiate and configure in your model after auth:

rpx = local_import('rpxauth')
rpxAuth = rpx.RPXAuth(auth)
#rpxAuth.embed = True
#rpxAuth.allow_local = True
rpxAuth.api_key = "..."
rpxAuth.realm = "..."
rpxAuth.token_url = "http://localhost:8000/[yourapp]/default/user/login"

You can change or add provider-to-auth field mappings. This is a dictionary that maps an RPX field to an auth_user field. There are built in mappings for Google and Yahoo. Here is how you can create another mapping:

 rpxAuth.mappings.MyOpenID = dict(identifier="identifier",
                               username="preferredUsername",
                               email="email",
                               first_name="givenName",
                               last_name="familyName")

There is an on_mapped attribute that you can use to alter the user fields before they are put in the database. In the case of Yahoo, the profile doesn't contain a separate first and last name so we can use on_mapped to split the name into separate fields. In your model:

def split_name(user,provider):
    if provider=="Yahoo":
        pcs = user.first_name.split(" ")
        user.first_name =pcs[0]
        user.last_name = pcs[-1]
    return user

rpxAuth.on_mapped = split_name

There is an rpx_disabled attribute to control which auth functions are disabled when allow_local is active and a user logs in with RPX. The default list of disabled functions is:

rpxAuth.rpx_disabled = ['register','retrieve_password',
                     'reset_password','change_password','profile']

For example, if you wanted to allow RPX users to modify their profile:

rpxAuth.rpx_disabled.remove('profile')

Now we just need to return our rpxAuth instance in our user function instead of the auth:

def user():
    return dict(form=rpxAuth())

You can toggle embed and allow_local for different behavior:

Javascript popup:

rpx

Embedded:

rpxembed

Embedded with local auth:

alt text

That's it!. RPX is an attractive option for simplifying your user management, allowing your application to accept logons from up to 6 providers using their free offering and up to 12 providers with their 'plus' product.

Related slices

Comments (4)


Hosting graciously provided by:
Python Anywhere