socialcast / devise_oauth2_providable

Rails3 engine integrating OAuth2 authentication with Devise
MIT License
219 stars 102 forks source link

clear session before Devise::Oauth2Providable::TokensController#create to work with iPhone #21

Open atomgas opened 12 years ago

atomgas commented 12 years ago

see: https://github.com/atomgas/devise_oauth2_providable/commit/2bbf960f513e1fc53c9938ef6eb00032880c50ad

wireframe commented 12 years ago

I'd like to keep the devise_oauth2_providable gem as close to the official oauth2 spec as possible. since the spec does not allow for deletion of access tokens, i'd prefer that this functionality be moved to an unofficial gem extension.

lgalabru commented 12 years ago

Hello there,

In order to avoid this problem, I've found another workaround. I'm flushing my iOS cookies with the following snippet:

    NSHTTPCookie *cookie;
    NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (cookie in [storage cookies]) {
        if ([[cookie domain] isEqualToString:@"yourdomain.com"]) {
            [storage deleteCookie:cookie];
        }
    }

Hope it'll help. Regards,

mackross commented 12 years ago

Also NSMutableURLRequest has a setHTTPShouldHandleCookies: method that allows you to turn off cookies for that request.

masterkain commented 11 years ago

I think that the session.clear workaround is good to have, I'm experiencing the same exception, not on iOS but in a quick test I was writing.

If I instantiate a OAuth2::Client and attempt to get the token with the same auth code, it raises: http://pastie.org/private/nz3cas3aamm0vgcqizwpw

This is just a quick, unfinished test to evaluate devise_oauth2_providable vs doorkeeper. With the session.clear workaround I'm able to properly receive the error invalid_grant, otherwise 500. Using Capybara's reset! won't do anything.

fatshotty commented 11 years ago

Hello, My opinion is that devise should ignore session cookies in this case. session.clear workaround is not good because it makes user unauthorized (he should relogin).

I'm writing a chrome extension that will use OAuth2 as authorization layer. This will lead to a scenario like this:

  1. open a chrome window (or tab, it's the same) and just login the rails application using user/password starting a new session.
  2. start an OAuth2 authorization "dance" through the developed extension (this means same cookies == "same session ID")

In this case with session.clear you will invalidate also the session at point 1, that is not what I would expect. I think that just leaving cookies out of OAuth2 scope would do the job.

Am I missing something?

Thanks in advance

samuraisam commented 11 years ago

:+1: needs fixed :)

I'm using this workaround for iOS AFNetworking library:

//
// AFNetworking subclasses ---------------------------------------------------------------------------------------------
//

@interface CTHTTPClient : AFHTTPClient
@end

@implementation CTHTTPClient

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters
{
    NSMutableURLRequest *req = [super requestWithMethod:method path:path parameters:parameters];
    [req setHTTPShouldHandleCookies:NO];
    return req;
}

@end

@interface CTOAuth2Client : AFOAuth2Client
@end

@implementation CTOAuth2Client

- (NSMutableURLRequest *)requestWithMethod:(NSString *)method path:(NSString *)path parameters:(NSDictionary *)parameters
{
    NSMutableURLRequest *req = [super requestWithMethod:method path:path parameters:parameters];
    [req setHTTPShouldHandleCookies:NO];
    return req;
}

@end
mcarlson commented 11 years ago

Here's how I worked around this issue using Rack middleware, which felt cleaner than hacking session.clear into app/controllers/devise/oauth2_providable/tokens_controller.rb:

lib/cookie_filter.rb

class CookieFilter
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['PATH_INFO'].match(/^\/oauth\/token/)
      env.delete "HTTP_COOKIE"
    end

    @app.call(env)
  end
end

Then I added this to config/application.rb:

require 'cookie_filter'
...
    # prevent cookies from screwing up devise_oauth2_providable
    config.middleware.insert_before ::ActionDispatch::Cookies, ::CookieFilter
raimo commented 10 years ago

+1