Rails return to specific location with route - ruby-on-rails

I have a link on a page that is for users who are not signed in yet. I want this link to redirect to the login_url, which upon logging in will redirect the user back to that page they were on.
Something like this would be great but I don't know how to route this.
Currently, I have a redirect_back helper but that only works on specific actions where you need to be signed in. This is just a link.
The login url is /login and I would like something like this:
("/login?return_to=" + #user.username)
for the link so when you click the link (say on the user jcl), it takes you to /login?return_to=jcl. Then after signing in with a POST request, it returns you to that user's page.
Is there specific routes or helpers that can accomplish this?

you can use a before_filter to save the url in the session and before login you redirect the user to the url in the session.

Related

With OmniAuth 2.0, how do we redirect to the IdP on failed authentication in Rails with with Devise?

OmniAuth 2.0 requires that requests to the IdP authentication server be POSTs instead of GETs.
What this means for most users is that on their login page, where they have links to OmniAuth providers like Facebook and Google, they change the method on those links or buttons to be POSTs. No problem.
But for one of my apps, we want it so that if authentication fails (like coming to the app and you need to login still) we redirect in a custom Devise::Failure App to the IdP authentication server. This means you come to our app with a GET request, of course, and we see you're not authenticated so we redirect you to the IdP. But we can't do that anymore because it has to be a POST. The only way I can see around it is I have to remove our custom Failure App so that you're redirected to the normal login page where our link to the IdP is.
Any ideas on how I can keep our current redirect straight to the IdP logic?
The answer is you can't do that with OmniAuth 2.0. You're not going to be able to redirect your DeviseFailureApp to the IdP's login page because that's going to be a GET.
Instead, have your Failure App return a redirect_url to a new controller action you can add in your SessionsController. I called it saml_redirect. Add a route for it:
devise_scope :user do
match 'saml_redirect' => 'sessions#saml_redirect', as: :saml_redirect, via: [:get]
end
That controller action doesn't really have to do anything but render an .html.erb. In that html.erb, simply have a hidden button which will do the POST to the IdP's login page, same as if you had a button to Facebook and a user clicked it. Then when the page loads, you automatically click the button. Here's the full code of the html.erb:
<div class="info_box">You are being redirected to your corporate network sign-in page</div>
<%= button_to "Login with #{ENV['saml_idp_name']}", user_saml_omniauth_authorize_path(provider: :saml), method: :post, id: 'saml_button', style: 'display: none' %>
<script>
function ready(callbackFunction){
if(document.readyState != 'loading')
callbackFunction();
else
document.addEventListener("DOMContentLoaded", callbackFunction);
}
ready(() => {
document.getElementById('saml_button').click();
})
</script>
So no rocket science here. The name of the game is if you want a user to automatically go to the Identity Provider's page when they need to login instead of forcing them to click a button from your login page, then you simply automate the clicking of the button.

Devise If logged in automatically send to home page

I have a base installation of Devise with everything setup and working correctly. I have a 'welcome' page and a 'dashboard' page which only logged in users can get to.
What I'm trying to achieve is to make all logged in users automatically skip the landing page and land straight on the dashboard when they come back to the site.
e.g.
I sign up from the landing page
I'm logged in
I close off chrome and go for food
I open chrome and go to the root url (example.com)
I get presented with my dashboard instead of the welcome page as I am logged in.
Any help is greatly appreciated
You should be able to do a simple check in the controller for if the session is active and if so redirect_to dashboard_path
I havent used devise in forever so I don't remember if they have a built in current_user (see the current_user setup here) method or not, but checking if that is nil would be a good check.
You need to create an after sign in devise method in your application controller:
def after_sign_in_path_for(resource)
your_after_sign_in_path
end
That should redirect all users to your_after_sign_in_path after they sign in.

Rails: redirect back to previous page after sign in / sign up

I am using Rails and devise for user authentication, I don’t know how to redirect the user back to the previous page after successful sign in/sign up.
I know about after_sign_in_path_for, but I don’t know what I should write inside.
You can write custom sessions controller for devise login and use request.referrer to get the URL of the page the user is coming from. Then just redirect back to the previous page after login. Also refer this doc. You could go by one of the methods. Hope it helps.

Creating Facebook Pages That Point to Different Subdomain URLs

My Ruby on Rails app has a subdomain URL for each user's public page. Eg. username.xyz.com
I want to publish this URL on the user's Facebook Page from Rails.
So far, I have created a Facebook App and set it's Page Tab and URL.
I'm using the fbgraph gem to set this app on the facebook page. (This page will be created by the user and will have admin access of this page.)
I used this code:
user = FbGraph::User.me("USER_TOKEN")
account = user.accounts.select {|account| account if account.name == "PageName"}.first
page = FbGraph::Page.new(account.identifier).fetch(:access_token =>"Access_token",:fields => :access_token)
tab = page.tab!(:app_id => "APP_ID_I_CREATED")
Using this code, every user's page points to the URL defined in the APP's Page Tab URL.
I want every user's page to point to their own subdomain URL (eg: user1.xyz.com)
What do I need to do to achieve this?
The subdomain is not handled by the web server, it's handled by DNS. So first you need to get DNS to route everyuser.xyz.com to the IP address where your web server is.
The way DNS works, you will likely have to have a DNS entry for every user. You might be able to find an API to add DNS subdomains when you create a user.
Don't ask me about how to do this, because I don't know, and am uninterested in researching it.
You also have to get the web application to accept the request, and #lightyrs has a good description on how to do that.
You can do the following:
Edit: Make all of these user.mywebsite.com subdomains resolve to the same URL. At that URL:
Create a catch-all route that will handle all traffic originating from *.facebook.com.
Point that route to a controller action that decodes params[:signed_request].
The decoded signed request will yield the facebook id of the page that is responsible for the request.
Fetch the user in your system that is an admin of the page in question.
Fetch the user's subdomain.
Redirect to the subdomain.
Currently, this is the most common way of solving this problem, however, I'd like to see a solution from facebook in the future that allows us to have some kind of dynamic tab URL based on the page, user, and referral context.

Devise sign in and registration forms from somewhere else in my app

I am building an e-commerce style site which lists products that you can buy. When you click on buy it takes you through to a URL like: http://shopfront.com/deal/123/buy.
I would like to provide Devise sign up and sign in on that buy page. I can currently get users to sign up and upon a successful sign up they will be redirected back to my buy page for the item they are interested in but if they provide insufficient details, they get redirected to devise's default sign up form which displays the error they encountered. Afterwards they are no longer redirected to my buy page and instead end up on the home page.
I have my own registrations controller which is where I am doing the redirect back to the relevant buy page on successful sign ups but I cannot figure out how to redirect unsuccessful sign ups back to the buy page.
I need to implement more or less the same functionality for a sign in form which will be displayed next to the sign up form on that same buy page. Any assistance would be appreciated.
Nice way is to store client state in session
put something like,
session[:return_to] = request.fullpath
in your controller, you may like to put this in private method
In general "in session", means to store data in cookies,
as session store points by default to
Rails::Application.config.session_store
=>
ActionDispatch::Session::CookieStore

Resources