I have a component configured as a beforeDispatch listener. This component checks if a form was POSTed, then checks that the CSRF token was properly sent. If not, it's supposed to forward to a special CSRF notification page. I specifically want to do a forward and not a redirect, so that users have the option of reporting which page they visited.
Here is my code:
public function beforeDispatch(\Phalcon\Events\Event $Event,\Phalcon\Mvc\Dispatcher $Dispatcher){
if($this->request->isPost()){
if(!$this->checkToken()){
echo 'before';
$Dispatcher->forward(['controller'=>'index','action'=>'csrf']);
echo 'after';
exit();
}
}
}
All I get is a page that displays "beforeafter". If I take those echos out, I just get a blank page. I can visit /index/csrf/ manually and it displays the page I want.
Why is the request not getting forwarded? Is this out of the dispatch loop?
You have coded:
exit();
?
I'm not sure you can use forward here has the dispatcher does not yet know if the controller and action exist yet in the dispatch loop. https://docs.phalconphp.com/en/3.2/dispatcher#dispatch-loop
But I think you can intercept and control what the controller class and action the dispatcher should execute using.
$dispatcher->setModuleName(<your module nam if you have one>);
$dispatcher->setNamespaceName(<your controller class>);
$dispatcher->setActionName(<your action name>);
Check the docs on dispatch loop
Related
Can I redirect to the previous page someone if not logged in? Also, is it possible to create a hierarchy system for users?
I tried this:
if(!(Auth::check())) {
header("Location: {{ route('cooperado.index') }});
}
But i not even got an error message, just doesn't work. I'm starting at laravel so it's kind of hard to fully understand how it works.
Using Constructor in controller
You also can use middleware in order to redirect unauthenticated user back or somewhere else.
public method __construct(){
$this->middleware('auth');
}
Add this code in your controller so all methods within particular controller
-direct from route defination
Route::get('/path/',controller#method)->name('cooperado.index')->middleware('auth');
Redirection
using this method unauthenticated user will redirect to login page.
in order to edit redirection page you can change '#redirectTo' method
in
app/Http/Middleware/Authenticate.php
file.
if(!(Auth::check())) {
return redirect()->route('cooperado.index');
}
You mention in your question also wants to return previous page then use following but i'm not recommended this because if your first login effort fails then login failed' page becomes your previous page and second login effort succeeds then you are redirected to login page again because it's your previous page.
return Redirect::to(URL::previous());
You can use this. Is the easiest way to do this.
And you can also pass message, will displayed on when user redirect back from main page.
if(!Auth::check) {
return Redirect::back()->with('error','Please Login');
}
I am re-writing the authentication process for my application running under ZF2.
I need to have more options to authenticate the user depending on the service called.
I.E. for web application accessed from browser I will authenticate via Ldap and for API services I will check the user credentials in the header.
I created an abstract controller checking if the user is authenticated; if not it will be redirected to login page.
All the controllers in the modules needing the same authentication process will extend this class.
I need to save the original request to redirect it back to it after successful login.
My questions are:
1. Is the abstract controller -> onDispatch() method the right
place to place it?
Every solution I found around was always doing it in the Module.php. To distinguish the auth method they need to check if the requested controller match, since Module.php is called always. Isn't it 'cleaner' to set it in the controller?
2. Should I use redirect or forward to pass from original controller
to login controller and then back?
I don't mind the url changing in the browser bar, just looking for the best and fastest solution keeping also original request.
3. Is it correct to store the uri in the session class ( from the
auth module)? Is there any way to conserve the whole request (including maybe the POST data in case needed)?
Here is the abstract controller:
abstract class AbstractAuthActionController extends AbstractActionController {
public function onDispatch(MvcEvent $e) {
$serviceManager = $e->getApplication ()->getServiceManager ();
$auth = $serviceManager->get ( 'LdapAuth\Client\Ldap' );
if (! $auth->hasIdentity ()) {
$uri = $e->getRequest()->getRequestUri();
$callBackFunction = $this->getLdap ()->getCallBackFunction (); // = new SessionData();
$callBackFunction::setOriginalUri($uri); // function to store temporarly the uri
return $this->redirect ()->toRoute ( 'ldap-login-route' );
} else {
return parent::onDispatch ( $e );
}
}
}
A lot of people do that because they want to take care of checking authentication before the controller dispatch event. Authentication can be checked much earlier in the process, for example on route event, or at least before the controller has been instantiated (dispatch with higher priority then controller).
In case the user is unauthenticated you want to respond with a 401 (unauthorized) or 403 (forbidden) or a 302 (moved temporarily) response (read some more background on this status code here on Wiki) as early as possible to prevent all the overhead which only keeps your server (unnecessarily) occupied and thus slows down your application and delays the unauthenticated response.
module.php is NOT the best place to add all the authentication related code. Better would be to create an authentication listener (and inject a authentication service in the listener) and only connect the listener in your module.php.
Read on the difference between redirect and forward here in this answer. If want to redirect the client that it is not properly authenticated in a response with a 302 status code you will need to send a redirect response including this status code. I also see people using forward in such cases, but in my opinion it is not correct, because the client won't get notified about any redirection. You could also check authentication modules like ZfcUser to see how they handle this.
You don't need to store this url on the server, you can send the url you want to go to after logging in (the original url) inside the redirect response. For example you redirect to login.php from a request targeted at profile.php, then your redirect url could look like this:
http://www.example.com/login.php?redirect=profile.php
You can now set the redirect inside the login process/controller so that after a successful login you return the client to to profile.php.
I'm running into an issue when using event dispatch in Magento.
I'm using controller_action_predispatch to set a frontend session variable from a parameter in the URL.
Now, the issue seems like, when the user comes to the site initially, they might lend on a page that will redirect them to base URL (such a example.com to www.example.com).
But for some reason, after redirect, the session variable is lost...
Any ideas?
Thank you.
EDIT:
adding the code used:
public function grabRef($observer) {
$ref = Mage::app()->getRequest()->getParam('ref', $default);
if (isset($ref) && !is_null($ref) and !empty($ref)) {
Mage::getSingleton('core/session',array('name'=>'frontend'))->setRefid($ref);
}
}
There are only two remotely useful events dispatched prior to this redirection, but they are not specific to the redirect:
controller_front_init_before
controller_front_init_routers
The redirect depends on the "Auto-redirect to Base URL" setting from System > Configuration > Web > Url Options, which is evaluated by Mage_Core_Controller_Varien_Front->_checkBaseUrl(). This redirect occurs before any dispatching takes place, and it does not append GET or POST data, hence the loss of the param you are trying to capture.
Normally sessions are initialized under adminhtml or frontend session namespace based on the controller class being used (ref the action controller superclass method Mage_Core_Controller_Varien_Action->preDispatch(). You should be able to move your observer configuration under global/events/controller_front_init_before. Note that you must do this in the global event area, as the frontend event configuration part does not load until after this event is dispatched. That particular scenario cost me an hour once!
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between redirect and forward in Zend framework
I'm new to zend framework, when i try to use foward, redirect, setViewRender in controller, what are their diffences?
As the official docs say:
_forward($action, $controller = null, $module = null, array $params = null): perform another action. If called in preDispatch(), the
currently requested action will be skipped in favor of the new one.
Otherwise, after the current action is processed, the action
requested in _forward() will be executed.
_redirect($url, array $options = array()): redirect to another location. This method takes a URL and an optional set of options. By
default, it performs an HTTP 302 redirect.
Read more to understand it better.
i'm pretty sure that a redirect redirects you to a particular page/ controller therefore going through all of the pre view processes including if you can view the page, setViewRender will just output the view you have selected and disregard all of the stuff the controller etc handles. (i haven't used zend for a while however)
_redirect creates a completely new http request, where as _forward simply forwards the request. I realized this when setting a variable in zend_registry, well this might sound a little off the track but when you use _request all the request variables and headers and registry variables are completely reset where as in case of _forward it simply forwards all those things. This is like you can have previously provided information along with some more information in case of _forward.
Well for setViewRenderer I really like this idea, I mean this is something like dependency injection. You dont really need to have a default view, you could provide a new view for the given action. I think you would get the best answer if you look into this.
_forward is an internal redirect. Where as _redirect sends a header that tells the client's browser to go to some other URL, _forward tells the Dispatcher to internally redirect the request somewhere else.
If you consider the normal dispatch order of:
preDispatch()
someAction()
anotherAction()
postDispatch()
Calling _forward at any point in that progression will cause the following steps to not be executed. So if you call _forward in preDispatch(), someAction() will not be called and so on. If you _forward() in someAction() and you are using the viewRenderer action helper to render your views (you are letting the framework choose what view script to render), then no view script will be rendered in someAction().
When the request is forwarded to the new Controller / Module the entire dispatch process will be repeated there.
Note:
If you forward inside someAction() to anotherAction() you must do it like this
return $this->_forward('another');
You should add a return to $this->_forward() or your current Action will continue to execute before forwarding to the other Action.
Also note that the view that will be rendered will be another.phtml
While when doing a redirect, ZF would instruct the browser to load http://example.com/controller-name/action-name as _redirect() sends a header, meaning you create a new HTTP Request and go through the entire dispatch process with it.
Last to render a certain view inside an action use the viewRenderer Action helper:
// Bar controller class, foo module:
class Foo_BarController extends Zend_Controller_Action
{
public function addAction()
{
// Render 'bar/form.phtml' instead of 'bar/add.phtml'
$this->_helper->viewRenderer('form');
}
public function editAction()
{
// Render 'bar/form.phtml' instead of 'bar/edit.phtml'
$this->_helper->viewRenderer->setScriptAction('form');
}
public function processAction()
{
// do some validation...
if (!$valid) {
// Render 'bar/form.phtml' instead of 'bar/process.phtml'
$this->_helper->viewRenderer->setRender('form');
return;
}
// otherwise continue processing...
}
}
I am checking an ACL in the pre-dispatch method of an ACL Action Helper. If the action is-allowed, the controller/action should continue as per normal. (No problems there). If it's NOT allowed, however, I would like to:
leave the requsted URI in the browser
skip executing the requested action method
generate an 'access denied' message
At first I thought I would just call _forward() in the Action Helper, but I can't since it's a protected method. The View Renderer Action Helper says that gotoSimple is like _forward, however it still performs the full http redirect (and thus changes the URI in the browser).
I could try calling setScriptPath() on View, then Render(), however this would not prevent the requested controller/action from firing. I think there's probably a straightforward answer to this, but it's beyond my level of experience!
Any assistance appreciated!
This is most easily solved by simply throwing a Zend_Controller_Action_Exception, preferably with code 401 (Unauthorized).
This will be caught by the error handler plugin and forwarded to the Error controller.
You can then check for this error code and handle it appropriately. This is in my error controller
if ($errors->exception->getCode() == 401) {
$this->getResponse()->setHttpResponseCode(401);
return $this->_forward('unauthorized');
}
The "unauthorized" action just displays a view but you could do more with it (log an error for example)