Camping OpenID Consumer

Here’s a snippet of code that gives you instant OpenID Authentication. It will set @state.identity to the user’s OpenID URL once they’ve logged in, so you’ll need to be using some kind of camping session handler. You’ll also need to install the OpenID gem from JanRain by running “gem install openid” in a terminal. It’s lovely for your user’s as they can login with existing Yahoo, AOL, LiveJournal, etc accounts, not needing to register for your app, and you get to skip writing all that annoying account creation & management code and get straight down to business!

Drop this code in your controllers, and make a form somewhere with an input by the name ‘openid_identifier’ with it’s action pointing to /login in your app. That’s all there is to it! To check if the user is logged in from various controllers in your camping app, do something like ‘return redirect(‘/index’) unless @state.identity’. The .identity property contains a unique URL which you use the same way you’d use a username normally. To add a log out link to your app, you just need to make a controller that does @state.delete(’identity’) :)

    class Login < R ‘/login’
      def get
        require ‘openid’
        this_url = ‘http:’ + URL(‘/login’).to_s
        unless input.finish.to_s == ‘1′
          # start doing the auth here
          begin
            request_state = Hash.new
            oid_request = OpenID::Consumer.new(request_state, nil).begin(input.openid_identifier)
            oid_request.return_to_args['finish'] = ‘1′
            @state.openid_request = Marshal.dump(request_state)
            redirect(oid_request.redirect_url(‘http:’ + URL(‘/’).to_s, this_url))
          rescue OpenID::DiscoveryFailure
            return ‘Couldn\’t find an OpenID at that address, are you sure it is one?’
          end
        else
          # finish the auth here
          request_state = Marshal.restore(@state.openid_request)
          response = OpenID::Consumer.new(request_state, nil).complete(input, this_url)
          @state.delete(‘openid_request’)
          case response.status
          when OpenID::Consumer::SUCCESS
            @state.identity = response.identity_url.to_s
            return redirect(R(HomeScreen))
          when OpenID::Consumer::FAILURE
            ‘The OpenID thing doesn\’t think you really are that person, they said: ‘ + response.message
          end
        end
      end
    end