Redirect after login using params - ruby-on-rails-3

Currently, when you login as a user, regardless of where from, you are taken to your homepage. I would like to check for params in the url and redirect based on that param.
Here's the code:
def after_sign_in_path_for(resource)
if params['redirect'] == 'SomeParameter'
return special_url
else
return home_url
end
end
If I use the regular login form with no params, I get taken to home_url. When I try to go to /user/login?redirect=SomeParameter, I still get taken to home_url. By the way, both routes are valid (if I just test special_url, it works just fine).
What am I missing?

Does the home page redirect you to the login form if you aren't signed in?
Devise will store the page that you were on when you attempted to log in, and redirect to it when you log in.
This will take precedence over the after_sign_in_path_for, so if you are going Home page => Auto-redirect to Login => log in, then the return value of the after_sign_in_path_for doesn't matter.
If that is the case, you can play with stored_location_for (Devise and stored_location_for: how do you store the return location?) to alter where you go.

Related

Redirect User to original URL after Google login in Flask

I have implemented flask-dance and authlib Flask client for Google sign-in, one answer was unclear in all implementations were how to redirect a user to original user once they login. For example, a flow I wanted => clicks on /results checks if not logged in redirect to login makes them login and then again redirects back to results with logged in session.
I saw some answers using state and kwargs addition but didn't see any clear answer or a pseudo code implementation.
If you have implemented such a scenario please answer the question it will help a lot or you can also reference to your Github projects if implemented
The simple solution i discovered to my own problem was in any implementation for any such library use a session variable to record orignal url and then redirect user after login using that variable so in here i have used next param variable which stores it temp then once authorized sends user to orignal url what they asked for
see the code below
#app.route('/login')
def login():
google = oauth.create_client('google')
redirect_uri = url_for('authorize', _external=True)
return google.authorize_redirect(redirect_uri)
#app.route("/dashboard")
def protect():
if not session.get('profile'):
session['next']='/dashboard'
return redirect('/login')
if session['profile']:
#load dashboard
else:
return "forbidden"
#app.route('/authorize')
def authorize():
google = oauth.create_client('google')
token = google.authorize_access_token()
resp = google.get('userinfo')
user_info = resp.json()
user = oauth.google.userinfo()
session['profile'] = user_info
session.permanent = True
redirecti=session.get("next",None)
return redirect(redirecti)

Rails: Doorkeeper custom response from context

We are using Doorkeeper gem to authenticate our users through an API. Everything is working fine since we've implemented it few years ago, we are using the password grant flow as in the example:
resource_owner_from_credentials do |_routes|
user = User.active.find_for_database_authentication(email: params[:username])
if user&.valid_password?(params[:password])
sign_in(user, force: true)
user
end
end
Doorkeeper is coupled with Devise, which enable reconfirmable strategy. As you can see in the code above, we are only allowing active users (a.k.a users with a confirmed email) to connect:
User.active.find_.....
Problem
Our specifications changed and now we want to return a different error on login (against /oauth/token) depending if the user has confirmed its email or not.
Right now, if login fails, Doorkeeper is returning the following JSON:
{
"error": "invalid_grant",
"error_description": "The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}
Ideally, we want to be able to return a custom description if and only if the current email trying to login is unconfirmed
We've checked the documentation on Doorkeeper but it does not seems to have an easy way (if any at all) to do this. The fact that resource_owner_from_credentials method is located in the config adds too much magic and not enough flexibility.
Any ideas ?
Ok so after digging a little bit, we found an easy way to work around this issue by overriding Doorkeeper::TokensController.
# frozen_string_literal: true
class TokensController < Doorkeeper::TokensController
before_action :check_if_account_is_pending, only: :create
private
def check_if_account_is_pending
user = User.find_by(email: params['username'])
render json: unconfirmed_account_error if user && !user.confirmed?
end
def unconfirmed_account_error
{ error: 'invalid', error_description: 'You must validate your email address before login' }
end
end
We also needed to make sure the routes were pointing to the custom controller:
use_doorkeeper do
controllers tokens: 'tokens'
end
Hope it can helps someone in the future

How to identify the current user when redirected from an auth0 rule

My authentication flow is as follows...
User visits my site and clicks login.
They are redirected to mydomain.auth0.com (or something like that), where they are prompted to login using either a username or password or a social provider e.g. Google.
Following the user's login, I run a custom rule in Auth0 to detect if they are a new user. If yes I now want to redirect them to a custom page to collect some additional data. I do this my implementing the following in the rule:
function (user, context, callback) {
context.redirect = {
url: 'http://www.example.com/profile'
};
callback(null, user, context);
}
This redirects the user back to my site adding a ?state=xyz... to the query string.
However, at this point I don't have a token or id token and seemingly no way to identify the user.
The example given at Auth0 talks about using this flow to force a user to update their password on login. However, for this to work there has to be some way to identify the user on the page they are redirected to.
What is the best way to get this working?
Here is a snippet from a Rule that redirects users to a post authentication registration page. Just pasting the section related to altering context.redirect since that is what you are asking about.
var hasPostRegistered = user.app_metadata && user.app_metadata.has_post_registered;
// redirect to consent form if user has not yet consented
if (!hasPostRegistered && context.protocol !== 'redirect-callback') {
var auth0Domain = auth0.baseUrl.match(/([^:]*:\/\/)?([^\/]+\.[^\/]+)/)[2];
var userId = user.user_id;
context.redirect = {
url: configuration.REGISTRATION_FORM_URL +
(configuration.REGISTRATION_FORM_URL.indexOf('?') === -1 ? '?' : '&') +
'auth0_domain=' + encodeURIComponent(auth0Domain) +
'&user_id=' + encodeURIComponent(userId)
};
}
Notice how the user_id is tagged on as a query param.
Note also, you can self-sign a JWT token inside a Rule, and send that to your redirect endpoint, which in turn can be configured to read / verify that JWT Token as a way to secure the redirection.

In coldfusion: how to remember that a user has logged in?

I have a username/password on a login page, which goes to 'member' page. Basically, I used a statement that finds the number of rows in a SQL query, and if it's not 1 (the correct username/password combination), then it redirects back to the login page.
However, on the 'member' page, there are forms to do various things, like add new rows to a table using SQL, or return queries of joined tables. These forms also link back to this 'member' page, but the conditions for logging in (which requires a username variable and password variable) would no longer be met.
So, how do I get the server to remember whether a user is logged on or not?
In the application.cfm or application.cfc, you will need to enable sessionManagement = true so you can start tracking variables across page requests. Then when a user logs in, you will set a variable like isAuthenticated = true. Only redirect to the login page if the isAuthenticated = false or undefined (you can set a default using cfparam in onSessionStart of Application.cfm)
Rough example, assuming you are using ColdFusion 9+
Application.cfc
component {
this.name = 'myApplication';
this.SessionManagement = true;
public function onSessionStart() {
param name='session.isAuthenticated' default=false;
}
}
checkAuthentication.cfm
<cfscript>
if (!session.isAuthenticated) {
// send to login page
}
</cfscript>
In your login processing page, make sure you set session.isAuthenticated to true, and then it should skip checking / asking for the login. You can also look into the built-in authentication functions of CFLOGIN.
Hope that helps a bit.

subdomain,testing using cucumber or capybara and rspec

Some part of the development of my project has been done.Our
company asks me to write cucumber test cases for the developed code
and for the henceforth development as well.
The routes file have two subdomains for admin and hosts.Devise is also
being used.
Now i installed cucumber and have written the first scenario for the
first story when the non registerd user lands on the home page,enters
a valid email and gets redirected to the next page..the page has no
password field.
Scenario: Non registered user lands on beta home page.
Given: I am on the homepage
When: I enter valid email with "bahubalian...#gmail.com".
Then: I should be redirected to request invitation page.
The problem is in my routes file, I have,
constraints :subdomain => ADMIN_SUBDOMAIN do
....
root :to => admin#index
end
constraints :subdomain => HOST do
...
root :to => home#index.
end
Now how do i specify the path.rb file to look for the root_path in
that specific subdomain.
Theres no root_path written outside the subdomain constraints.
This is my first time with testing.
I am really stuck onto this.Any help is deeply appreciated.
I just got to know from somebody that this can be implemented using capybara.If so ,could you please give a little idea about it.
Turned out it was pretty simple.Capybara provides a default_host method.
So I just needed to mention,
When I visit subomain sub
And then the webstep
Given /^I visit subdomain (.*)$/ do |site_domain|
site_domain = "http://sub.example.com" if site_domain == "admin"
Capybara.default_host = site_domain
visit "/"
end
Update:
default_host is not supposed to be used as it is not mentioned in the docs.
Instead try using absolute path in visit.
Given /^I visit subdomain (.*)$/ do |site_domain|
site_domain = "http://sub.example.com" if site_domain == "admin"
visit site_domain
end