Redirect user to 2FA page Laravel - php

I've got a working login page for my Laravel program. Now, if the user logs in successfully he/she must be redirected to a different page (instead of the "home" page as they normally would have been). This will be the 2FA page.
My question is:
I know how to redirect the user after validating their credentials, but how can I set it so that once the user is redirected to the 2FA page that they cannot instantly access any other part of the website as they would after logging in normally? (Also, they should only be able to access the 2FA page if they've been authenticated successfully) And then only allow them access to the full content of the website only after they've passed the 2FA page?
My login function in my AuthController looks something like this:
if (Auth::attempt(['username' => $request->username, 'password' => $request->password])) {
return redirect()->route('home');
} else {
session()->flash('errormessage','Invalid password.');
return redirect()->back();
}
As far as I know, "Auth::attempt" immediately logs the user in when True is returned. One way I was thinking of doing it is I instantly log the user out as soon as they're logged in, save their UserID to their session, then redirect them to the 2FA page, the 2FA page checks their UserID in their session and loads, otherwise redirects them back to the login page. And once they've passed the 2FA page just log them in again using their UserID which is saved in their session.
Any better suggestions would be welcome.

Add this function to your login controller which overrides the redirectTo property
public function redirectPath()
{
if(some condition)
{
$this->redirectPath=route("some where");
}else{
$this->redirectPath=route("some other where");
}
return $this->redirectPath;
}

Related

Laravel. Log in to comment

I have to create ,,log in to comment" button. On click this button should redirect user to login page and after successfull loging in, he should be redirected to page, where he have clicked that button. I tried to make fake url with auth middleware around it like this:
Route::group(['middleware' => 'auth'], function() {
Route::get('/log-in-to-comment', 'UserController#getLogInToComment');
});
I have defined my getLogInToComment function like this:
public function getLogInToComment() {
return redirect()->back();
}
But it redirects me to /log-in-to-comment which is already in filter so I get too many redirects. Also I have tried return Redirect::to(URL::previous()); but it also doesn't work. As far as I know, post method should not be used on redirects, so how do I deal with this simple task? Thanks in advance!
Since Laravel always redirects back to the page you came from (which is in your case /log-in-to-comment), you have to overwrite this URL.
A possible way to do so is to fetch the URL of the last site and an save it to the browsers session. To do so, make sure the getLogInToComment-route is not using auth or guest middleware, since it should be processed as a guest as well as a signed in user. Then, store the previous site if the user is not logged in, and redirect back to it if he is.
public function getLogInToComment() {
if (!Auth::user()) {
// User is not logged in. Save previous URL and redirect to login
Session::put('prev', URL::previous());
return Redirect::route('login');
} else {
// User is now logged in and returned to this route again. Redirect to site
return Redirect::to(Session::get('prev'));
}
}
By having ['middleware' => 'auth'], you are forcing the user to already be logged in to see the log-in-to-comment page.
I will also note that you don't need the leading / in the route path.
Try:
Route::group(['middleware' => 'guest'], function() {
Route::get('log-in-to-comment', 'UserController#getLogInToComment');
});

CakePHP redirect to previous URL after login

I am using CakePHP 2.2.0, When a user is not logged in, when a link is clicked, it goes to the login page, after login i would like to redirect to the initial link that was clicked. Anybody knows how we can implement it using CakePHP? I tried with the $this->referer() but it seems not getting the previously visited URL. If anybody knows please help me to sort out!
If you need to redirect to the referer page you can use:
$this->redirect($this->referer());
Reference: http://book.cakephp.org/2.0/en/controllers.html#flow-control
In the method processing the login, you could redirect to
$this->Auth->redirectUrl()
This should work:
if ( $this->Auth->login() ) {
return $this->redirect( $this->Auth->redirect() );
}
From the doc:
The above code (without any data passed to the login method), will
attempt to log a user in using the POST data, and if successful
redirect the user to either the last page they were visiting, or
AuthComponent::$loginRedirect. If the login is unsuccessful, a flash
message is set.
if ($this->Auth->login()) {
$this->Session->write('SESSION_DATA_HERE', 1);
return $this->redirect( $this->Auth->redirect() );
} else {
$this->Session->setFlash("Username or Password is incorrect.Please try again.", 'error');
$this->redirect($this->referer());
}
Validate Auth User, if tru then redirect to the last visit page otherwise to the login screen from which user logged in by providing username and password
Actually, you can do this by adding some back_url to your Log In link and then you can use that value for redirecting users.
Something like this:
<?php
// log in link
echo $this->Html->link('Log In', '/login?back_url='.$_SERVER['REQUEST_URI']);
// log in action
$back_url = $this->request->query('back_url');
if($back_url === null) $back_url = '/';
// ... some other code
if($this->Auth->login()) {
$this->redirect($back_url);
}
?>

Issue Codeigniter redirect( ) cached

I am using the Codeigniter redirect() to redirect the page after user logouts on my website http://www.theindianclassified.com.
When user goes to the url http://www.theindianclassified.com/logout he is redirected to the home page after he is logged out of the system. But if the user login and again click logout user is not logged out but he is redirected to the home page. I think the redirect using the Codeigniter redirect() method is cached by browser.
Please help me, how the implementation happen in the above scenario. I want the browser not to cache the redirect.
Log out function is below.
function logout() {
$this->session->sess_destroy();
redirect('');
}
You should check your login function to make sure the fault isn't there. If I were to guess it'll be there. If that doesn't work try 'unsetting' the session variables one-by-one.

Take user back to previous page after logging in?

I have a controller called Accounts, with the views signin and signout.
The corresponding functions look like this:
function signin()
{
if (!empty($this->data))
{
//handle login
...
//save login to session
$this->Session->write('Account', $data["Account"]);
//redirect to previous page
???
}
}
function signout()
{
//delete login
$this->Session->delete('Account');
//redirect to previous page
???
}
If the user goes to accounts/signin it first checks to see if the form is submited if(!empty($this->data)) if yes, it logs them in, if not it renders the signin form. If they do succesfully log in, I want to redirect them to the page they were at before the signin page.
Whats the best way to do that?
Edit:
I do not think I can user a regular http referrer because technically the referrer will always be the signin in page because they go to /signin, then submit the sign in form. So at the point where the form is submited the referrer is always /signin. I want to redirect to where they were before that. Does that make sense?
the best way is to use cakes Auth component and let it do what it does... http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
Here's how I do it with referer
I have 2 login forms, one is a form at the top of all pages for easily sign in, the other is on login action. If the user comes in using the form at the top, the form submission then goes to login page and you can use $this->referer() to redirect the user back.
But the problem is that, if the user types the password wrong or enter invalid credential, he will then end up on the login page. If he then enters the right username+password, and redirection occurs using $this->referer(), which in this case is itself. The user then could then either 1. get redirected back to login page again or 2. even worse can get stuck in an infinite loop b/c login will keep redirecting to itself.
So, I add some logic to check to make sure that referer is not login page. Also, I add another logic to store $this->referer() the first time the user lands on login page, we we know where exactly the page before login page.
To store the page before login page, put this code at the end of the action (login view rendering is about to begin)
//get the current url of the login page (or current controller+action)
$currentLoginUrl = strtolower( "/" .$this->name ."/" .$this->action );
if( $this->referer() != $currentLoginUrl )
{
//store this value to use once user is succussfully logged in
$this->Session->write('beforeLogin_referer', $this->referer($this->Auth->redirect(), true)) ) ; //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead
}
Now put the code to redirect in the part of the code where authentication is succesful (or in if( $this->Auth->user() ){ } ):
//get the login page url again (by gettting its controller, or plural of Model, and this current page action and make the url)
$currentLoginUrl = strtolower( "/" .$this->name ."/" .$this->action );
//if the referer page is not from login page,
if( $this->referer() != $currentLoginUrl )
{
//use $this->referer() right away
$this->redirect($this->referer($this->Auth->redirect(), true)); //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead
}
else
{
//if the user lands on login page first, rely on our session
$this->redirect( $this->Session->read('beforeLogin_referer') );
}
Hope this works for you.
http://book.cakephp.org/view/430/referer
Use a hidden <input> field that holds the initial referrer and gets submitted with the login data.
I don't know about the best way, but I store the attempted destination in a session variable before redirecting them to the sign in page.
Once they have signed in, I redirect them to the stored destination.
Use the AppController and UsersController to set it up
In AppController beforeFilter action
$referer = Router::url($this->url, true);
$this->Auth->loginAction = array('controller'=>'users','action'=>'login','?'=>['referer'=>$referer]);
In UsersController login action
if($this->Auth->login())
{
$this->Session->setFlash(__('Logged in successfully !'));
$redirect = $this->request->query('referer');
if(!empty($redirect))
{
return $this->redirect($this->Auth->redirectUrl($redirect));
}else{
return $this->redirect($this->Auth->redirectUrl());
}
}
CakePHP 2.x here
1. Edit AppController.php
public function beforeFilter() {
// redirect url
if($this->request->here!= '/users/login') {
$user_id = AuthComponent::user('id');
if(empty($user_id)) { $this->Session->write('redirect_url_after_login', Router::url($this->request->here, true)); }
}
This will store the url the user wanted to go before request, only if the url is not /users/login (replace with your url of login) AND if no user is logged.
2. Edit your login form. Mine was Users/login.ctp. Add an hidden field only if there is a session variable set.
$redirect_url_after_login = $this->Session->read('redirect_url_after_login');
if(!empty($redirect_url_after_login))
echo $this->Form->input('redirect_url_after_login', ['value'=>$redirect_url_after_login, 'type'=>'hidden']);
3. In your login action, add an action to overwrite the loginRedirect variable you may have set before.
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$redirect_url_after_login = $this->request->data['User']['redirect_url_after_login'];
if(!empty($redirect_url_after_login)
&&filter_var($redirect_url_after_login, FILTER_VALIDATE_URL)
&&parse_url($redirect_url_after_login, PHP_URL_HOST)==$_SERVER['HTTP_HOST'])
return $this->redirect($redirect_url_after_login);
$this->Session->delete('redirect_url_after_login');
return $this->redirect($this->Auth->redirect());
}
I added a couple of security checks, like "is the redirect url a valid url?" and "is it redirecting towards my domain or an external domain?".
Note: I know checking $_SERVER['HTTP_HOST'] is not bulletproof, but here we're talking about preventing open redirect vulnerability, so it's enough.

CakePHP authentication breaking after an incorrect login

I have a simple login form, username and password. Basically, When a user is anywhere on the website, he can click a link that will take him to the login page. After login, he is redirected to the page he came from initially.
The problem:
let's say I was in the "/posts" page, and I clicked to login, so now I am on "/users/login".
- if the login is correct, or the login is incorrect and nothing is filled in the username textbox, everything works as expected (if it's correct I am redirected back to "/posts" otherwise I receive the "wrong username or password" message, I try to login again correctly and then I am redirected to "/posts";
if the login is incorrect, and some text is filled in the username textbox, after the login I receive the "wrong username or password" message, which is good, but if I fill in the form again, no matter wheather it is correct or not, I get "You are not authorized to access that location." If I try to log for the third time, the login works, but I am redirected to "/users/posts" instead of "/posts" (the value for the redirect page, which is stored in a session, is still "/posts" ).
This is the code:
function beforeFilter () {
parent::beforeFilter();
$this->Auth->allowedActions = array( 'confirmation');
$this->Auth->fields = array(
'username' => 'usr_username',
'password' => 'usr_password'
);
$this->Auth->userScope = array('User.usr_confirmed' => 1);
if($this->action == 'signup') {
$this->Auth->authenticate = $this->User;
}
}
function login () {
if ( $this->Auth->user() ) {
$this->redirect($this->Session->read('page'));
exit();
}
}
function logout () {
$this->Session->destroy('username');
$this->redirect('/');
exit();
}
it sounds like your form action is redirecting to a restricted area. check the form action attribute.
Put this at the bottom of app/views/layouts/default.ctp to help debug the session:
<?php debug($session->read()); ?>
The Auth.User key will be filled with data when you are logged in, but, more importantly, the Auth.redirect key will containing the URL of the last restricted page visited, this is where AuthComponent plans on redirecting to once you log in.
Are you storing a restricted page's URL in the your session's page key?
If so, AuthComponent can provide that functionality already with its Auth.redirect key. All you need to do is link to the restricted page instead of the login page and AuthComponent will populate that key automatically and handle the redirect after login.
echo $html->link('Login', array('controller' => 'users', 'action' => 'profile'));
If not, then why not consider populating that key instead. Since AuthComponent already checks for and acts on this key, you might gain some free functionality.
In any event, here is what a custom login method should look like in your case, but if any of the advice above will work then you can simply leave out the login method all together and use the default functionality:
function login () {
// log the user in
if ($this->Auth->login()) {
// your session redirect
if ($this->Session->read('page')) {
$this->redirect($this->Session->read('page'));
}
// auth's session redirect
if ($this->Session->read('Auth.redirect')) {
$this->redirect($this->Session->read('Auth.redirect'));
}
// default redirect
$this->redirect($this->Auth->loginRedirect);
}
}

Categories