songkick / oauth2-provider

Simple OAuth 2.0 provider toolkit
MIT License
529 stars 148 forks source link

Wondering if this wrapper works on Rails 2.3.14 & Ruby 1.8.7 #43

Closed cavi21 closed 11 years ago

cavi21 commented 11 years ago

Hi there! I'm asking this because I implemented this on a ror 2.3.14 project without any issues at first, but seams the the problem is when I try to retrieve the token. This is how is implemented following the example:

Routes availables

 /apps/authorize [get, post]
 /apps/allow [post]
 /apps/login [post]

I got the feeling that something is missing for the token (regarding I handle in the /apps/authorize route with the parameter request_type=token

in the authorize action I have

 @owner = ( current_user.nil? ) ? nil : current_user
 @oauth2 = OAuth2::Provider.parse(@owner, request.env)

 if @oauth2.redirect? && @oauth2.error.blank?
    redirect_to @oauth2.redirect_uri, :status => @oauth2.response_status
    return
 end

 if @oauth2.response_body.blank?
    render and return
 elsif @oauth2.valid?
    render :action => "login" and return
 else
    redirect_to root_path
 end

I got everything working but i can't solve the issue how to retrieve the token

I missing something or maybe is not compatible with this rails version or ruby (for instance the force_ssl I can't use because of the version of rails)

If anyone could point me if I'm missing something or anything I'll really appreciate it, I run out of ideas

Thanks a lot Cheers

jcoglan commented 11 years ago

It should work on these versions -- see the build. http://travis-ci.org/#!/songkick/oauth2-provider

A few tips:

The final section should just be something like:

headers.update(@oauth2.response_headers)
if body = @oauth2.response_body
  render :text => body, :status => @oauth2.response_status
else
  render :action => 'login'
end

In the login/allow forms, you embed the values of the params in @oauth2.params -- these are the credentials given by the client when redirecting to /apps/authorize and need to be passed through. Then in your allow action, you have code to grant access to the client and redirect to it. This will give the client an access token, if they asked for response_type=token.

@oauth2 = Songkick::OAuth2::Provider.parse(current_user, request.env)
if params[:allow]
  @oauth2.grant_access!
else
  @oauth2.deny_access!
end
redirect_to @oauth2.redirect_uri, :status => @oauth2.response_status

Look at the application in the ./example directory, look at how data is passed through it. It's Sinatra, but it should be obvious how to map it onto Rails APIs.

jcoglan commented 11 years ago

I also strongly recommend setting Songkick::OAuth2::Provider.enforce_ssl = true -- this should work back to some fairly old versions of Rack. If you have a reverse proxy like Apache in front of your app that terminates the SSL connection, just make Apache set X-Forwarded-Proto: https header when it forwards in SSL request to your Rails app.

cavi21 commented 11 years ago

Hi James! thanks a lot for the quick response.

Regarding the latter comment, I can't put the enforce_ssl = true because through me an error with the rack 1.1.3, I updated the rack but other gems (don't remember which one, I think it was activesupport 2.3.14 in actionpack) depends on rack 1.1.x so. I ended forcing with the reverse proxy as you mention.

I tweak my code with your comments, the only thing I think I don't get it is when you reference the allow action because seams to me that, that's the code for the authorize action.

In my allow action (where the resource owner give permission the the client app) i have:

 @user = current_user
 @auth = OAuth2::Provider::Authorization.new(@user, params)
 if params['allow_access'] == 'allow'
    @auth.grant_access!
 else
    @auth.deny_access!
 end
 redirect_to @auth.redirect_uri, :status => @auth.response_status

In the allow and the login forms I had the @oauth2.params embed in the hidden.

I follow the example, the only part I'm lost is how the other OAuth client wrapper (in a php application) could get the token?

cavi21 commented 11 years ago

Hi again! well I want to share my experience with rails 2.3.14, the problem is how handle the json response in a smart way.

Maybe I'm missing something but the big issue was that no matter how you set the headers in a response rails (at least that version) give more importance to the render :whatever command, so if you have

 render :text => body, :status => @oauth2.response_status, :headers => @oauth2.response_headers

will render everything as a :text response and in my case I also handle the authorization screen in the same action so I need to check if there is something in the response_headers of the @oauth2 instance (after I check the @oauth2.response_body of course) so I could handle the :json response and also the :html response. I agree is not the nicer way to do it, neither the most elegant, but was the only way I found to get this working with little changes and validations.

Thanks James for the support and your responses! If you want you can close this issue!