Simple Dynamic Paths #585

Closed
mbleigh opened this Issue Mar 6, 2012 · 8 comments

Comments

Projects
None yet
4 participants
@mbleigh
Contributor

mbleigh commented Mar 6, 2012

A feature that has been requested (and implemented by others) is the ability to specify "dynamic" paths. I think that using a regular expression matcher or other forms of "route-like" behavior are simply too heavy for OmniAuth. However, I do want to support more powerful custom pathing for OmniAuth so here's my proposal:

The :request_path and :callback_path options (as well as any additional path options specified by strategy gems) should take a lambda in addition to a string and consider themselves on the respective path for a provider if the lambda evaluates truthily. For example:

use OmniAuth::Builder do
  use :developer, :request_path => lambda{|env| env['RACK_ENV'] == 'development' && env['PATH_INFO'].include?('/auth') }
end

@mbleigh mbleigh referenced this issue Mar 6, 2012

Closed

Dynamic paths #548

@emiltin

This comment has been minimized.

Show comment
Hide comment
@emiltin

emiltin Mar 6, 2012

how will the dynamic bit of the callback url be set to reflect the request path?

emiltin commented Mar 6, 2012

how will the dynamic bit of the callback url be set to reflect the request path?

@mbleigh

This comment has been minimized.

Show comment
Hide comment
@mbleigh

mbleigh Mar 6, 2012

Contributor

Hmm...good point. There are two potential ways to go here:

  1. Callback paths aren't dynamic. This would be (mostly) fine so long as the originating request path was available, and most OAuth 2 providers don't allow you to set dynamic callbacks anyway (you must be explicit).
  2. The lambda passed to :request_path returns either nil/false, true, or a string. If it's a string, use that string as the callback path.

In either case the callback path would likely be stored in the session and dereferenced.

Contributor

mbleigh commented Mar 6, 2012

Hmm...good point. There are two potential ways to go here:

  1. Callback paths aren't dynamic. This would be (mostly) fine so long as the originating request path was available, and most OAuth 2 providers don't allow you to set dynamic callbacks anyway (you must be explicit).
  2. The lambda passed to :request_path returns either nil/false, true, or a string. If it's a string, use that string as the callback path.

In either case the callback path would likely be stored in the session and dereferenced.

@emiltin

This comment has been minimized.

Show comment
Hide comment
@emiltin

emiltin Mar 6, 2012

the point of dynamic paths is that they're.. well dynamic, so i i'm not sure i understand option 1 :-)
i suppose option 2 would work. you parse "auth/facebook/blogs/23", and return "auth/facebook/blogs/23/callback", which will then be called after facebook returns

emiltin commented Mar 6, 2012

the point of dynamic paths is that they're.. well dynamic, so i i'm not sure i understand option 1 :-)
i suppose option 2 would work. you parse "auth/facebook/blogs/23", and return "auth/facebook/blogs/23/callback", which will then be called after facebook returns

@mbleigh mbleigh closed this in a682ba1 Apr 12, 2012

@mbleigh

This comment has been minimized.

Show comment
Hide comment
@mbleigh

mbleigh Apr 12, 2012

Contributor

@emiltin could you take a look at master and its new dynamic callback stuff and see if what it does is suitable for your original request? If so, I'm ready to package up OmniAuth 1.1 and ship it!

Contributor

mbleigh commented Apr 12, 2012

@emiltin could you take a look at master and its new dynamic callback stuff and see if what it does is suitable for your original request? If so, I'm ready to package up OmniAuth 1.1 and ship it!

@emiltin

This comment has been minimized.

Show comment
Hide comment
@emiltin

emiltin Apr 13, 2012

thanks, will try to find time to look at it!

emiltin commented Apr 13, 2012

thanks, will try to find time to look at it!

@emiltin

This comment has been minimized.

Show comment
Hide comment
@emiltin

emiltin Jun 14, 2012

trying understand how to use this. should i add :request_path to each provider? for example:

provider :twitter, TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET,
:setup => true,
:request_path => lambda{ |env| env['PATH_INFO'].include?('/auth/twitter') }

this causes an error when i start rails: TypeError (can't convert Proc into String)

what i need is to accept auth paths in the form: /auth/twitter/:id, with callbacks going to /auth/twitter/:id/callback (similar for failures)

emiltin commented Jun 14, 2012

trying understand how to use this. should i add :request_path to each provider? for example:

provider :twitter, TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET,
:setup => true,
:request_path => lambda{ |env| env['PATH_INFO'].include?('/auth/twitter') }

this causes an error when i start rails: TypeError (can't convert Proc into String)

what i need is to accept auth paths in the form: /auth/twitter/:id, with callbacks going to /auth/twitter/:id/callback (similar for failures)

@nlsrchtr

This comment has been minimized.

Show comment
Hide comment
@nlsrchtr

nlsrchtr Jul 13, 2012

@mbleigh I ran into the same issue today.

The background: I'm using subdomains for my customers, but Facebook is forcing me to use one domain to redirect the users after authentication. So after authentication, the users gets redirected to this URL, but I don't know anymore from which subdomain the users started the request. (And no, I don't like a cookie-based approach here.)

Starting at https://xyz.domain.com/auth/facebook, the user is now redirected to https://www.domain.com/auth/facebook/callback.

What I'm looking for is to overcome this issue on a per request base, so I can hand in the subdomain (or any other param) into the callback_url, like f.e. https://www.domain.com/auth/facebook/callback/subdomain/:subdomain

For now I overcome this problem with the following piece of code in the initializer:

provider :facebook, ..., ..., :setup => lambda{ |env| env['omniauth.strategy'].options[:callback_path] = "/auth/facebook/callback/subdomain/#{env['SERVER_NAME'].split('.').first}" }

This doesn't feel "the right way". Is there any other solution? If would also be okay to work as a prefix solution, like:
https://www.domain.com/subdomain/:subdomain/auth/facebook/callback/

Would be nice if you could give me your thought on this. Thank you!

@mbleigh I ran into the same issue today.

The background: I'm using subdomains for my customers, but Facebook is forcing me to use one domain to redirect the users after authentication. So after authentication, the users gets redirected to this URL, but I don't know anymore from which subdomain the users started the request. (And no, I don't like a cookie-based approach here.)

Starting at https://xyz.domain.com/auth/facebook, the user is now redirected to https://www.domain.com/auth/facebook/callback.

What I'm looking for is to overcome this issue on a per request base, so I can hand in the subdomain (or any other param) into the callback_url, like f.e. https://www.domain.com/auth/facebook/callback/subdomain/:subdomain

For now I overcome this problem with the following piece of code in the initializer:

provider :facebook, ..., ..., :setup => lambda{ |env| env['omniauth.strategy'].options[:callback_path] = "/auth/facebook/callback/subdomain/#{env['SERVER_NAME'].split('.').first}" }

This doesn't feel "the right way". Is there any other solution? If would also be okay to work as a prefix solution, like:
https://www.domain.com/subdomain/:subdomain/auth/facebook/callback/

Would be nice if you could give me your thought on this. Thank you!

@javidjamae

This comment has been minimized.

Show comment
Hide comment
@javidjamae

javidjamae Feb 4, 2013

@nlsrchtr - I have the same exact issue with subdomains on Facebook. I'm curious if you found a better way. I am trying out your listed solution, but I'd be interested in seeing how you actually handled the routing in the routes file.

@nlsrchtr - I have the same exact issue with subdomains on Facebook. I'm curious if you found a better way. I am trying out your listed solution, but I'd be interested in seeing how you actually handled the routing in the routes file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment