OpenID on GAE

98 views
Skip to first unread message

Will Stevens

unread,
Mar 29, 2011, 1:21:13 PM3/29/11
to web2py-users
I am trying to get both the basic auth and open id working together on
GAE. I have managed to get it working on the web2py.py server, but I
still have some minor issues with GAE. It has taken me about 2 days
to get to this point, and I am SOO close to having a perfectly working
setup.

My configuration is as follows:
== db.py ==
from gluon.contrib.login_methods.openid_auth import OpenIDAuth
openid_login_form = OpenIDAuth(auth)

== controller ==
def user():
if 'janrain_nonce' in request.vars: # if openid form has been
submitted
auth.settings.login_form = openid_login_form
return dict(form=auth())

if 'login' in request.args: # if we are on the login page
form = DIV(
DIV(auth()),
DIV(openid_login_form.login_form()))
else:
form = auth()

if 'profile' in request.args: # if we are on the profile page
form = DIV(form, openid_login_form.list_user_openids()) # append
the openid's for this user to the login form (also appends the 'add
openid' form)

return dict(form=form)

This appends the OpenID login form to the 'login' page. It also
appends the 'list openids' to the profile page. If the openid form is
submitted it will be caught by the first if statement in the
controller and get handled by auth.

NOTE:
On line 244 of gluon/contrib/login_methods/openid_auth.py there is bug
that I had to fix in order for this to work.
- self.db.alt_logins.insert(username=oid, user=user)
+ self.db.alt_logins.insert(username=oid, user=user.id) #changed user
to user.id to get rid of db error...

With this configuration I have been able to successfully (on default
server):
- login using the basic auth form.
- view my profile and see the openid list (with form).
- in the profile, add an open id to the list.
- in the profile, remove an open id from the list.
- login using the associated openid for a specific user.
(everything works as expected)

On GAE I have the following:
- login using the basic auth form. (works)
- view my profile and see the openid list (with form). (works)
- in the profile, add an open id to the list. (see note below)
- in the profile, remove an open id from the list. (works)
- login using the associated openid for a specific user. (works)

The main problem I have now is that when I associate an OpenID with an
account (aka - on the profile page, enter an openid into the form and
then click 'Add'), I have the following symptoms...

I am taken to a page that has the following on it:
URL:
http://localhost:8080/init/default/user/login?_next=/init/default/user/profile&janrain_nonce=2011-03-29T17%3A16%3A35ZfAY3Z0&openid.ns=http%3A%2F%2Fspecs.ope
... etc ... ntity=https%3A%2F%2Fprofiles.google.com
%2Fwilliamstevens&openid.claimed_id=https%3A%2F%2Fprofiles.google.com
%2Fwilliamstevens

Page Content:
[DB] profiles.google.com/williamstevens authenticated
Status: 303 SEE OTHER
Set-Cookie: session_id_cloudops="292:7dfe3917- ...etc... -
a0077e6f94f6"; Path=/
Content-Type: text/html; charset=UTF-8
Location: /init/default/user/profile

You are being redirected <a href="/init/default/user/profile">here</a>


I need this redirect to actually happen and not just be shown on the
page to the user. If I can make that redirect happen, I have finally
made this work.

Please let me know if you have any ideas.

Thanks,

Will

Will Stevens

unread,
Mar 29, 2011, 2:47:56 PM3/29/11
to web2py-users
I have continued debugging, so I figured I would add some more
details.

In the controller here...
if 'janrain_nonce' in request.vars:
auth.settings.login_form = openid_login_form
return dict(form=auth()

I printed out the value of 'request.vars' in a debugger.

=> request.vars
<Storage {
'openid.op_endpoint': 'https://www.google.com/accounts/o8/ud?
source=profiles',
'openid.sig': 'QRnWCdVM...etc...KhepWnPUMXg=',
'openid.return_to': 'http://localhost:8080/cloudops/dashboard/user/
login?_next=/cloudops/dashboard/user/
profile&janrain_nonce=2011-03-29T18%3A30%3A01ZLZP3X9',
'openid.response_nonce': '2011-03-29T18:30:02Z7_7VbUEUzcArkQ',
'janrain_nonce': '2011-03-29T18:30:01ZLZP3X9',
'openid.ns': 'http://specs.openid.net/auth/2.0',
'openid.claimed_id': 'https://profiles.google.com/williamstevens',
'openid.mode': 'id_res',
'_next': '/cloudops/dashboard/user/profile',
'openid.signed':
'op_endpoint,claimed_id,identity,return_to,response_nonce,assoc_handle',
'openid.assoc_handle': 'AOQobUfNex0ZNZ...etc...V8nfOdio9KotL-
XnWCGoWB1b9IwN',
'openid.identity': 'https://profiles.google.com/williamstevens'
}>

Does anyone see anything in this that seems wrong???

Thanks,

Will
> URL:http://localhost:8080/init/default/user/login?_next=/init/default/use...

Will Stevens

unread,
Mar 29, 2011, 2:54:03 PM3/29/11
to web2py-users
in the initial post, i change my app name to init and controller to
default cause that is what you would be expecting.

it is actually cloudops and dashboard, but i have everything
configured for that to work...

i did not change the urls in the latest printout, so i wanted to make
a note of that.

Will Stevens

unread,
Mar 29, 2011, 4:07:08 PM3/29/11
to web2py-users
I have continued testing and I have further confirmed that the only
time I am having the redirect issue of:
[DB] profiles.google.com/williamstevens authenticated
Status: 303 SEE OTHER
Set-Cookie:
session_id_cloudops="292:7dfe3917-16a3...etc...a0077e6f94f6"; Path=/
Content-Type: text/html; charset=UTF-8
Location: /cloudops/dashboard/user/profile

You are being redirected <a href="/cloudops/dashboard/user/
profile">here</a>



Is when the 'user' controller is called with the following
'request.vars':
<Storage {
'_formkey': '6085d1f2-295d-4cce-aef4-27591a06898e',
'oid': 'https://profiles.google.com/williamstevens',
'_formname': 'default',
'_next': '/cloudops/dashboard/user/profile'
}>


This is when the 'list_user_openids()' form is submitted...

Will Stevens

unread,
Mar 30, 2011, 12:08:25 PM3/30/11
to web2py-users
I have continued battling with this. Still no luck...

Any input would be appreciated...

ws

Arbie Samong

unread,
Mar 30, 2011, 12:45:54 PM3/30/11
to web2py-users
Hey man you may want to use janrain which also supports openid. I use
it for my app and it works fine. Massimo explained the setup here:

http://blip.tv/file/4912976

Regards,
Arbie

Will Stevens

unread,
Mar 30, 2011, 1:03:18 PM3/30/11
to web2py-users
Ya, I had setup Janrain previously and it worked, but my application
needs control (or at least awareness) of which login types are being
used and are associated with a user.

The good new is that I JUST FIGURED IT OUT!!! :)

My setup:
I have both the regular auth setup as well as openid, so on the login
page, you will have both forms. On the profile page, you can
associate an openid with your account, after which you will be able to
login using that openid.

*** NOTE: ***
I had to fix two bugs in 'gluon/contrib/login_methods/openid_auth.py'
to get this working...

gluon/contrib/login_methods/openid_auth.py on line 243
- print "[DB] %s authenticated" % oid
+ #print "[DB] %s authenticated" % oid
(this print statement was ok with the built in server, but on GAE
caused the redirect to not work because the print was output before
the headers were sent.)

gluon/contrib/login_methods/openid_auth.py on line 244
- self.db.alt_logins.insert(username=oid, user=user)
+ self.db.alt_logins.insert(username=oid, user=user.id) #changed user
to user.id to fix insert error


In my application:

== db.py ==
from gluon.contrib.login_methods.openid_auth import OpenIDAuth
openid_login_form = OpenIDAuth(auth)


== controller ==
def user():
if 'janrain_nonce' in request.vars: # if openid form has been
submitted
auth.settings.login_form = openid_login_form
return dict(form=auth())

if 'login' in request.args: # if we are on the login page
form = DIV(
DIV(auth()),
DIV(openid_login_form.login_form()))
else:
form = auth()

if 'profile' in request.args: # if we are on the profile page
form = DIV(form, openid_login_form.list_user_openids()) # append
the openid's for this user to the login form (also appends the 'add
openid' form)

return dict(form=form)


Thats it... I hope this will save others the hassle I have gone
through getting this working.

Cheers,

Will

Will Stevens

unread,
Mar 30, 2011, 1:09:49 PM3/30/11
to web2py-users
It is worth noting that you will need to get the python-openid package
from (http://pypi.python.org/pypi/python-openid/) and add the 'openid'
folder to the folder 'web2py/site-packages' in your project so it can
be referenced by 'openid_auth.py'


On Mar 30, 1:03 pm, Will Stevens <williamstev...@gmail.com> wrote:
> Ya, I had setup Janrain previously and it worked, but my application
> needs control (or at least awareness) of which login types are being
> used and are associated with a user.
>
> The good new is that I JUST FIGURED IT OUT!!!  :)
>
> My setup:
> I have both the regular auth setup as well asopenid, so on the login
> page, you will have both forms.  On the profile page, you can
> associate anopenidwith your account, after which you will be able to
> login using thatopenid.
>
> *** NOTE: ***
> I had to fix two bugs in 'gluon/contrib/login_methods/openid_auth.py'
> to get this working...
>
> gluon/contrib/login_methods/openid_auth.py on line 243
> - print "[DB] %s authenticated" % oid
> + #print "[DB] %s authenticated" % oid
> (this print statement was ok with the built in server, but on GAE
> caused the redirect to not work because the print was output before
> the headers were sent.)
>
> gluon/contrib/login_methods/openid_auth.py on line 244
> - self.db.alt_logins.insert(username=oid, user=user)
> + self.db.alt_logins.insert(username=oid, user=user.id) #changed user
> to user.id to fix insert error
>
> In my application:
>
> == db.py ==
> from gluon.contrib.login_methods.openid_auth import OpenIDAuth
> openid_login_form = OpenIDAuth(auth)
>
> == controller ==
> def user():
>     if 'janrain_nonce' in request.vars: # ifopenidform has been
> submitted
>       auth.settings.login_form = openid_login_form
>       return dict(form=auth())
>
>     if 'login' in request.args: # if we are on the login page
>       form = DIV(
>               DIV(auth()),
>               DIV(openid_login_form.login_form()))
>     else:
>       form = auth()
>
>     if 'profile' in request.args: # if we are on the profile page
>       form = DIV(form, openid_login_form.list_user_openids()) # append
> theopenid'sfor this user to the login form (also appends the 'addopenid' form)
>
>     return dict(form=form)
>
> Thats it...  I hope this will save others the hassle I have gone
> through getting this working.
>
> Cheers,
>
> Will
>
> On Mar 30, 12:45 pm, Arbie Samong <phek...@gmail.com> wrote:
>
>
>
>
>
>
>
> > Hey man you may want to use janrain which also supportsopenid. I use
> > > > > > >     if 'janrain_nonce' in request.vars: # ifopenidform has been
> > > > > > > submitted
> > > > > > >       auth.settings.login_form = openid_login_form
> > > > > > >       return dict(form=auth())
>
> > > > > > >     if 'login' in request.args: # if we are on the login page
> > > > > > >       form = DIV(
> > > > > > >               DIV(auth()),
> > > > > > >               DIV(openid_login_form.login_form()))
> > > > > > >     else:
> > > > > > >       form = auth()
>
> > > > > > >     if 'profile' in request.args: # if we are on the profile page
> > > > > > >       form = DIV(form, openid_login_form.list_user_openids()) # append
> > > > > > > theopenid'sfor this user to the login form (also appends the 'add
> > > > > > >openid' form)
>
> > > > > > >     return dict(form=form)
>
> > > > > > > This appends theOpenIDlogin form to the 'login' page.  It also
> > > > > > > appends the 'list openids' to the profile page.  If theopenidform is
> > > > > > > submitted it will be caught by the first if statement in the
> > > > > > > controller and get handled by auth.
>
> > > > > > > NOTE:
> > > > > > > On line 244 of gluon/contrib/login_methods/openid_auth.py there is bug
> > > > > > > that I had to fix in order for this to work.
> > > > > > > - self.db.alt_logins.insert(username=oid, user=user)
> > > > > > > + self.db.alt_logins.insert(username=oid, user=user.id) #changed user
> > > > > > > to user.id to get rid of db error...
>
> > > > > > > With this configuration I have been able to successfully (on default
> > > > > > > server):
> > > > > > > - login using the basic auth form.
> > > > > > > - view my profile and see theopenidlist (with form).
> > > > > > > - in the profile, add an open id to the list.
> > > > > > > - in the profile, remove an open id from the list.
> > > > > > > - login using the associatedopenidfor a specific user.
> > > > > > > (everything works as expected)
>
> > > > > > > On GAE I have the following:
> > > > > > > - login using the basic auth form. (works)
> > > > > > > - view my profile and see theopenidlist (with form). (works)
> > > > > > > - in the profile, add an open id to the list. (see note below)
> > > > > > > - in the profile, remove an open id from the list. (works)
> > > > > > > - login using the associatedopenidfor a specific user. (works)
>
> > > > > > > The main problem I have now is that when I associate anOpenIDwith an
> > > > > > > account (aka - on the profile page, enter anopenidinto the form and
Reply all
Reply to author
Forward
0 new messages