views:

1858

answers:

5

I'm playing with the authlogic-example-app and I'm failing to get the email address from the OpenID provider (in my case: Google and Yahoo) when I register a user, resp. I get an empty response instead of an email address (check the comments in code below).

This is how my user model looks like (everything else looks like the "with_openid"-branch of the authlogic-example-app mentioned above). Besides the missing 'email', the openid-authentication-process works as expected:

class User < ActiveRecord::Base
  acts_as_authentic do |c| 
    # not needed because I use OpenID
    c.validate_login_field = false
    # avoid failed validation before OpenID request
    c.validate_email_field = false
    # this one sets 'openid.sreg.required=email'
    c.required_fields = [:email]
  end

  private

  # overwriting the existing method in '/lib/authlogic_openid/acts_as_authentic.rb'
  def map_openid_registration(registration)
    # this is my problem: 'registration' is an empty hash
    self.email ||= registration[:email] if respond_to?(:email) && !registration[:email].blank?
  end

end

Any idea how to solve this? Has anyone here done this before using authlogic? Or even better: Do you have a working example?

Update: I checked the Google Account Authentication API and compared the request submitted by authlogic (using ruby-openid-gem and openid-authentication-plugin) with the example requests on the Google Account Authentication API docs:


Example request to authenticate and fetch email address by Google:

https://www.google.com/accounts/o8/ud
?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0
&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select
&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select
&openid.return_to=http%3A%2F%2Fwww.example.com%2Fcheckauth
&openid.realm=http%3A%2F%2Fwww.example.com%2F
&openid.assoc_handle=ABSmpf6DNMw
&openid.mode=checkid_setup
&openid.ns.ext1=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0
&openid.ext1.mode=fetch_request
&openid.ext1.type.email=http%3A%2F%2Faxschema.org%2Fcontact%2Femail
&openid.ext1.required=email


Request submitted by my appliation:

https://www.google.com/accounts/o8/ud
?openid.assoc_handle=AOQobUcdICerEyK6SXJfukaz8ygXiBqF_gKXv68OBtPXmeafBSdZ6576
&openid.ax.mode=fetch_request
&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select
&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select
&openid.mode=checkid_setup
&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0
&openid.ns.ax=http%3A%2F%2Fopenid.net%2Fsrv%2Fax%2F1.0
&openid.ns.sreg=http%3A%2F%2Fopenid.net%2Fextensions%2Fsreg%2F1.1
&openid.realm=http%3A%2F%2Flocalhost%3A3000%2F
&openid.return_to=http%3A%2F%2Flocalhost%3A3000%2Faccount%3Ffor_model%3D1%26_method%3Dpost%26open_id_complete%3D1
&openid.sreg.required=email

While debugging the whole setup, I've found out that the openid-authentication-plugin never receives an email in the response it receives from the openid provider, this at least explains why the registration hash in my user-model is empty...

UPDATE: If you're playing around with authlogic and openid, don't forget to check out the latest railscast on this subject!

A: 

Test against an OpenID server you control, since it'll let you debug every part of the OpenID sequence. There are no guarantees that Google's OpenID provider is doing the right thing. Try checking against Verisign's server, since I'm pretty sure that one at least should do the right thing with the openid.sreg.required=email field.

Your code snippet looks right to me.

Bob Aman
+7  A: 

As nobody could help me, I helped myself. :-)

The short answer to my question is:

c.required_fields = [:email,"http://axschema.org/contact/email"]

Using this line, the application requests the email-address using sreg and ax (request-type supported by Google).

You can find a more detailed answer and a working implementation of authlogic-openid with the Javascript OpenID-Selector right here:

http://github.com/vazqujav/authlogic_openid_selector_example/

Javier
I'm getting errors when these fields are enabled... undefined method `required_fields=' for #<Class:0x2643d84>... without them: #c.required_fields = ["http://axschema.org/contact/email"] # fetch email by sreg #c.optional_fields = ["email"] it works.
holden
@holden: I addressed this as reply to the github-issue you submitted.
Javier
+2  A: 

While this pointed me in the right direction, what I needed was:

c.openid_required_fields = [:email,"http://axschema.org/contact/email"]

This pulled in the email and set it.

Daniel Huckstep
+1  A: 
# fetch email by ax
c.openid_required_fields = [
                            "http://axschema.org/contact/email",
                            "http://axschema.org/namePerson/first",
                            "http://axschema.org/namePerson/last",
                            "http://axschema.org/contact/country/home",
                            "http://axschema.org/pref/language"
                           ]

This fetches in multiple values as specified @ http://code.google.com/apis/accounts/docs/OpenID.html#Parameters

Though I'm still unable to fetch in the country name... name, email, language works perfectly!

makuchaku
A: 

hi, the thing is i am able to fetch the parameters from the provider but am not able to extract them from the response... i have used OpenID::AX::FetchResponse.from_success_response(open_id_response) as the object to hold the response... what method do i use to extract email,nickname,country,etc...

pradnya shah