Symfony Action Security - How to forward after successful authentication? - php

With Symfony's Action Security if a user has not been identified he will be forwarded to the default login action as defined in the applications settings.yml file. How would I forward the user to the originally requested action after the user is successfully authenticated?

On first hit to your login action, store referer to the user session:
if(!$this->getUser()->hasParameter('referer'))
{
$this->getUser()->setParameter('referer',$this->getRequest()->getReferer());
}
and then when login succeeds, redirect user to stored referer with:
$this->redirect($this->getUser()->getParameter('referer'));
You have complete example in sfGuardPlugin:
http://www.symfony-project.org/plugins/sfGuardPlugin

More simply...
$this->getUser()->setReferer($this->getRequest()->getReferer());
like
setReferer($referer)
{
if (!$this->hasAttribute('referer'))
$this->setAttribute('referer', $referer);
}

A related problem, but instead trying to perform the forward from a different action:
If you have an action protected by sfGuard which is attempting to redirect to the referrer, you will get a redirect loop after signing in. This is because the sign-in page of sfGuard wil become the referrer. A parameter or attribute can be saved over multiple requests if stored in the sign-in action as above, meaning the action might be redirecting to an incorrect page if already signed in. The solution is to use a flash which will be forgotten. This can be accomplished with the following code in the executeSignin method of sfGuardAuthActions:
if ($this->getUser()->hasFlash('referer'))
{
$this->getUser()->setFlash('referer', $this->getUser()->getFlash('referer'));
}
else
{
$this->getUser()->setFlash('referer', $this->getRequest()->getReferer());
}
By resetting the flash in the first block, it won't be forgotten between login attempts, and by using a flash, signing in from other pages can't interfere with your action.

Related

How to avoid Laravel login redirect to latest AJAX call?

There are multiple ajax requests happening on the page and if a user logs in, the user gets redirected to the latest url via the following snippet:
public function showLoginForm()
{
if(!session()->has('url.intended')) {
session(['url.intended' => url()->previous()]);
}
return view('auth.login');
}
This url may be an ajax returning some json. How do I avoid the intended url being ajax? I obviously want it to redirect to the actual previous page instead of some random ajax call. Is the only way to avoid this by just saving the redirect url as a query param like /login?redirect_uri=/go-here-after-login ?
Also, if you have a totally different approach in mind, I'm all ears.
Thanks!
You should look into using redirect()->intended() for your purposes.
When an unauthenticated user tries to visit a page that is protected by the Auth middleware, they are redirected to your login page and only then is their intended URL (the URL they tried to visit) stored in the session.
When that user logs in, you can then redirect them to their intended page, or a fallback page of your choosing using redirect()->intended(). For example:
class LoginController
{
public function handleLogin()
{
if (Auth::attempt(request()->only(['email', 'password']))) {
return redirect()->intended('/your/fallback/url');
// Or if you want to get a URL by its route name:
// return redirect()->intended(route('route.name'));
}
// Handle what happens if the user's credentials were incorrect
}
}
As far as I am aware, every URL the user visits (via AJAX or otherwise) should not be stored in the session and it's only when the Auth middleware kicks in that the intended URL is set.
In your code you're using url()->previous(), which redirects the user to their referrer (The page that originated the request i.e. the previous page) rather than the intended URL stored in the session.

How to remember which URL the user was accessing before registration

I am developing a Laravel application and I need some suggestion.
I have a page which when a user who is not logged in access, it redirects to the login page and after authentication, he is back to the same. This works fine.
The problem is that if the user was a new user. He doesnot have a login and goes for Registration.
He then registers and the application redirects him to several other pages (like e.g.He needs to verify his email) and when all is done he will be on the dashboard page.
Now is there any way, I can save that he was on certain page and after registering and moving through all those pages come back to the same page?
Thanks,
Santhosh
Since you haven't posted any code I'd write a general explanation of how I think you should handle this.
In short - you can get the indented url and add it to the registration button as a query parameter i.e yourdomain.com/register?origin=some_route.
So assuming you have a register button/link on your login page, add the origin to the link href:
<a href="register?origin=some_route">Register<a>
This way, when you finish the registration, you can simply access the origin by using \Input::get('origin').
Now, to actually get the intended url you can either try and get it from the Session by using:
\Session::get('url.intended', url('/'))
or you could use \Redirect::intended(url('/'))->getTargetUrl();
In both cases url('/') is used as a fallback url to the homepage and you could replace it with any other url you wish.
Hope this helps!
I imagine you could do something like this for one page:
return redirect()->intended('/dashboard');
which would the the same as
return \Redirect::intended('/dashboard');
As per docs: https://laravel.com/docs/5.2/authentication#authenticating-users
The intended method on the redirector will redirect the user to the URL they were attempting to access before being caught by the authentication filter. A fallback URI may be given to this method in case the intended destination is not available.
Alternately, if you're going through a multi-page login 'wizard' type deal, I'd personally store the initial value of redirect()->intended in a Session or Cookie, and redirect to the value of the session / cookie once your registration process is complete.
Instead of intended redirect function you can print the HTTP referer in a hidden field in the form, then after login redirect to that URL.
<input type="hidden" name="redirect" value="{{URL::previous()}}">
Controller:
if(Input::get('redirect') && (Input::get('redirect') != url('/path/to/login/'))){
return redirect(Input::get('redirect'));
}
else{
return redirect('/alternative/page');
}

How can I deny users access to parts of my Backbone App if they have not logged in?

So I've got a Backbone application + web homepage. Right now, if you login to my website, I create a global object with your user details from the database. However, you can still just hit one of the routes in the application directly.
How should I handle users who are not "logged in" and redirect them to a "you must login page"?
Is this a standard operation? Basically, I have a REST url setup that returns just
{ sessionId: [php-session-id-here] }
If they are logged in, it would return something more like this:
{
sessionId: [php-sess-id],
userId: [user-id-from-db],
firstName: [f-name],
lastName: [l-name]
}
Ideas? Thanks!
What I've done in the past is to include on every page along with jQuery (actually, added to the jQuery file) an extension on the AJAX method to check for a custom code that I send when a user isn't logged in. When that value was seen it redirected the user to the login page regardless of what was going down.
This was because that site had a time out on login, so a user could get logged out while sitting on a page and then the AJAX request would just fail. If you don't have a timeout on the login the odds of ever seeing this issue are slim. Just ignore requests that come from users that aren't logged in.
If you need help coding this, start here: Extending Ajax: Prefilters, Converters, and Transports.
Really shouldn't require anything as complex as pseudo-code:
JS needs to do some AJAX, so JS talks to server
PHP checks for login if needed
If not logged in, send back the abort message (I used a converter to catch a "notLoggedIn" dataType. However this could also be done with a transport, they are just more complex.)
JS sees the abort message and does a window.location redirect rather than return AJAX message.
If you want, you could load a lightbox with a login form and send that via AJAX to PHP where a re-login can take place, if you remember the AJAX attempt that failed you can send it again after login. Then the user doesn't even need to leave the page to log back in.
If you're using jQuery, you can set a global ajaxSetting that allows you to do certain things upon certain http codes. Some pages I read recommend adding to your JSON a url field to point to where to login, but I figure that's just up to you. So the only modifications you'd need to implement what I've mentioned is 1. change the http code to something reasonable like 401 (unauthorized) and implement the http code handler. But I wouldn't call this standard, I'd just say that's what several people have done (including myself).
<?php
function IsLoggedIn()
{
if(isset($_SESSION['id'])) // Change that to what you want
{
return 1;
}
else
{
return 0;
}
}
?>
Then in your code, you could use something like:
if(isLogged()){ header('Location: http://google.com'); }

Redirect page after login in Yii framework

I am newbie to the Yii Framework. In Yii when you login by default it redirects to the index page. I want that when I will login to Yii the page will redirect to another page not the index page. So can anyone help me in this. Any help or suggestions will be highly appreciable.
[edit]
how the redirect will work when I will use user module as after login the page is redirected towards profile page?
You can (and indeed, must, if any redirection is going to take place) specify the URL to redirect to inside your controller's actionLogin method. After a successful login, you will see something like this code:
$this->redirect(Yii::app()->user->returnUrl);
Change this to any parameter that the CController::redirect method supports, and you can control where the user is redirected after login.
As an aside, using Yii::app()->user->returnUrl enables the redirect page to return the user back to the URL they intended to visit before being redirected to the login page.
To redirect the user to a page after login, create a new controller in gii for the page your user will be directed to after s/he logs in. I'll call this controller 'app' here. Gii will automagically create some files for you- one will be /protected/models/AppController.php
In AppController.php, you will have a default public function (method) called actionIndex. The purpose of this default method is to call (render) the /protected/views/app/index.php file (also created by gii for you). index.php is the file your users will see once they log in. That is the file you will want to modify to build your app. Go back to SiteController.php and change the argument of redirect() in the actionLogin() method
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login())
// since my controller is /protected/controllers/AppController.php
$this->redirect(array('app/index'));
}
This should get you started. (This is essentially my post on the discussion at
the yiiframework site)
you can redirect to site/index after logged in using user module.
'modules'=>array(
// user extension
'user'=>array(
...........
# page after login
//'returnUrl' => array('/user/profile'),
'returnUrl' => array('/site/index'),
........
),
),
$this->redirect($this->createUrl('yourcontroller/youraction'));

CodeIgniter: Dynamic post-login redirection?

I'm building a basic CodeIgniter site that requires a login before you can access any of the site.
If a user visits some site url, something like this:
http://www.mysite.com/project/detail/2049
AND they are current logged out, I have it set to automatically kick them back to the login page.
My question is, after they login, what is the best way to redirect them to the original URL they typed in, instead of say, redirecting them to the websites homepage?
I was thinking maybe, dynamically create the URL as a hidden form element in the login form and redirect there upon a successful login... What do you guys think? Is there a better/best practice for this type of dynamic post-login redirection?
When they hit the restricted page record the uri and set it as session data with
this->session->set_userdata('redirect', 'page/uri/here');
then redirect them to the login / register
after they login check to see if 'redirect' is present with
if($this->session->userdata('redirect'))
{
redirect($this->session->userdata('redirect'));
}
if it doesn't then take them wherever you normally take them after a login
when attempt to access is intercepted:
redirect('/public/login/r'.$this->uri->uri_string());
so in your case, after redirection the url might look like this:
http://www.example.com/public/login/r/project/detail/2049
if the login is successful
$uri = $this->uri->uri_string();
$redirect = substr($uri, strpos($uri, '/r/')+2);
redirect($redirect);
will redirect to the original resource.
(and no, the +2 should not be +3)
Why dont you create a session value upon login and then verify it on each page necessary to secure?
Build it into a library, so you can call the following:
$this->mylibrary->login($user);
and
$this->mylibrary->is_logged_in($user); on top of each page and automatically redirect visitors to your main site.
I am using flashdata to redirect.
this->session->set_flashdata('redirect_url', 'page/uri/here');
after they login check to see if 'redirect_url' is present with
if($this->session->flashdata('redirect_url'))
{
redirect(base_url().$this->session->flashdata('redirect_url')));
}
Hope this help

Categories