I want to stop the controller action when a block code is complete.
This some example code.
class Controller extends \Phalcon\Mvc\Controller {
/**
* Check if user have access
*
*/
protected function isAllowed($perm = false)
{
/**
* Always allowed if $perm not defined
*/
if (!$perm) {
return false;
}
/**
* if user not login
*/
if (!$this->authentication->isLoggedin()) {
/* Redir to login */
$this->response->redirect( $this->url->get('authentication/login') );
return false;
} else {
/* Check for user access */
if ($this->authorization->isAllowed($perm)) {
return true;
} else {
/* if not have access, it will be redir to index */
$this->flash->warning("U not have permission to access page");
return $this->response->redirect( $this->url->get('administrator/') );
}
}
}
}
and the another controller that extend from base is
class postController extends Controller {
/**
* Add group
*
*/
public function addAction()
{
/*
Check user access
this must redirect to login and stop exe script
*/
$this->isAllowed('group_add');
/*
But when i check with `Postman`
without auth i redirect to login.
but when i use post method and fill the header body like bellow.
i still redir to login but this code execute. why? and how to stop it.
*/
/* If request is POST */
if ($this->request->isPost()) {
/* Get all inputs from form */
$inputs = $this->request->getPost();
$name = $this->request->getPost('name', ['trim', 'striptags', 'string']);
$definition = $this->request->getPost('definition', ['trim', 'striptags', 'string']);
/* Filter validation */
if (!Validation::make($inputs, $this->rules())) {
$this->flash->error('...');
... redirect to page
return false;
}
/* Get from database */
$model = new AauthGroups;
$group = $model->findFirst([
'name = :name:',
'bind' => [
'name' => $name
]
]);
/* If cant find group then add it */
if (!$group) {
/* Set & save data */
$model->name = $name;
$model->definition = $definition;
$model->save();
$this->flash->success('Yay!! We found that name in database, do u want to change it?');
return;
}
/* If it finded than set flash error */
else {
$this->flash->error('Oops!! We found that name in database, do u want to change it?');
return;
}
}
}
}
I tried to use exit; but the view will not render. Can you explain it?
Can you try send()-ing the response like this?
/* Redir to login */
$this->response->redirect( $this->url->get('authentication/login') )->send();
return false;
If this does not work, you may have to use beforeExecuteRoute in your "BaseController".
class Controller extends \Phalcon\Mvc\Controller {
public function beforeExecuteRoute()
{
// Check if logged
if (!$notLogged) {
$this->response->redirect('....')->send();
return false;
}
}
I will be able to check those later. Hope it works for you by then.
Related
I;m working on a codeigniter project. I want to create a hook so that, it verify the user login every time when he load the class.
my Hook
$hook['post_controller_constructor'] = array(
'class' => 'Auth_login',
'function' => 'is_logged_in',
'filename' => 'Auth_login.php',
'filepath' => 'hooks',
);
and also enabled in the config file.
/**
* Auth_login
*/
class Auth_login
{
/**
* loading the CI instance
* #var [object]
*/
private $CI;
public function __construct()
{
$this->CI =& get_instance();
$this->CI->load->library('session');
$this->CI->load->helper('url');
}
/**
* Check the enduser for login verify, every time when the enduser
* loads the controller.
*/
public function is_logged_in()
{
/**
* if end user is not logged in, redirect to the login page
*/
if(!$this->CI->session->userdata('is_logged_in'))
{
$this->CI->session->set_tempdata('faliure','Please sign in to continue');
redirect(site_url('login/index'));
}
}
}
It checks for the session login verify for the end user. If user not logged in then redirect to the login page.
Here is my Controller where it redirects
class Login extends CI_Controller {
// class constructor
// public function __construct() {
// parent::__construct();
// // load default
// $this->load->model('login_model');
// }
/**
* [display the login page, and verify the login page using "form_validation" for server side validation]
* #return [redirect] [description]
*/
public function index()
{
$this->load->model('login_model');
// on form sumbit
$on_sumbit = $this->input->post('verify');
if(isset($on_sumbit))
{
// server side validation for login
if ($this->form_validation->run('login/login_verify') == FALSE)
{
$this->load->view('login');
}
else
{
// get the form post value
$user_name = $this->input->post('user_name');
$password = $this->input->post('password');
// verify login
$verified = $this->login_model->login_verify($user_name,$password);
if($verified) // success
{
redirect('dashboard');
}
else // failure
{
$this->session->set_flashdata('login_failure','Please check your email and password and try again');
redirect('login/index');
}
}
}
// login page
$this->load->view('login');
}
// delete active session
public function logout()
{
$this->session->sess_destroy();
redirect('login');
}
}
When it redirect to the login controller, it show errors like
since it working on the local system
"localhost redirected you too many times"
what is the actual problem with this. Any help would be appreciated.
You want to check if you are not on login controller or in other words you want to have hook functionality on every controller except login where you redirect if condition not met. You can exclude that controller in condition this way:
/**
* Auth_login
*/
class Auth_login
{
/**
* loading the CI instance
* #var [object]
*/
private $CI;
public function __construct()
{
$this->CI =& get_instance();
$this->CI->load->library('session');//working with sessions - you want sessions
//to be loaded ASAP so better way would be having it in
//APPPATH.'config/autoload.php' instead in all classes
/**
* #tutorial how to exclude hook interaction with particular class/controller
*/
if ( strtolower( $this->CI->router->class ) == 'login' )
{
return;
}
$this->CI->load->helper('url');
}
/**
* Check the enduser for login verify, every time when the enduser
* loads the controller.
*/
public function is_logged_in()
{
/**
* if end user is not logged in, redirect to the login page
*/
if(!$this->CI->session->userdata('is_logged_in'))
{
$this->CI->session->set_tempdata('faliure','Please sign in to continue');
redirect(site_url('login/index'));
}
}
}
Delete all sessions from \application\cache\session
In Yii 1.1.16 Observer Design Pattern is implemented using events & behaivours (events can be shared between all components that extends CComponents). I have following models:
User.php (see below)
Work.php (see below)
Activity.php
what I want to accomplish is following:
lets say in DefaultController:
<?php
public function actionExampleWork()
{
$work = new Work();
$work->description = 'some random description';
$work->created_at = new CDbException('NOW()');
$work->user_id = 1;
//$work->attach() INVOKE EVENT that will be handled by all models which listen to this event
$work->save();
}
public function actionExampleUser()
{
$user = new User();
$user->email = 'foo#example.com';
$user->username = 'example';
$user->password = '123';
//$user->attach( something ) invoke Event that should be handled only by Activity model
$user-> save();
}
?>
actually I have saw lot of examples Yii doing related things, but so far no success on finding answer that fit's my needs :(
Is this possible in Yii?
How can I implement this?
**Is there an alternatives (except manually handling method calls in controller actions)? **
User.php
<?php class User extends CActiveRecord
{
public function tableName()
{
//#return string the associated database table name
};
public function rules()
{
//#return array validation rules for model attributes.
};
public function relations()
{
return array(
'works' => [self::HAS_MANY, 'Works', 'user_id'],
);
}
public function attributeLabels()
{
//#return array customized attribute labels (name=>label)
}
public function search()
{
//#return CActiveDataProvider the data provider that can return the models
// based on the search/filter conditions.
}
public function updateLastActivity($user_id, $activity_type){
$user = $user->model()->findByPk($user_id);//find user
$user->activity_type = $activity_type;
$user->last_action = new CDbExpression('NOW()');//update DB column
$user->save; //save user
}
} ?>
Work.php
<?php
class Work extends CActiveRecord
{
public function tableName()
{
//#return string the associated database table name
}
public function rules()
{
//#return array validation rules for model attributes.
}
public function relations()
{
return array(
'user' => [self::BELONGS_TO, 'User', 'user_id'],
);
}
public function attributeLabels()
{
//#return array customized attribute labels (name=>label)
}
public function search()
{
//#return CActiveDataProvider the data provider that can return the models
// based on the search/filter conditions.
}
?>
You don't need an observer class for your scenario.
Using Built in Event Handlers
The Yii model class has a few built in functions that you can overwrite in your class.
Have a look at the official documentation for CActiveRecord for more detaiils.
http://www.yiiframework.com/doc/api/1.1/CActiveRecord
HINT: Search for beforeXXXX, afterXXXX, onXXXXX
As an example, here is my pre-persist handler for my user model.
/**
* Runs just before the models save method is invoked. It provides a change to
* ...further prepare the data for saving. The CActiveRecord (parent class)
* ...beforeSave is called to process any raised events.
*
* #param <none> <none>
* #return boolean the decision to continue the save or not.
*
* #access public
*/
public function beforeSave() {
// /////////////////////////////////////////////////////////////////////
// Some scenarios only require certain fields to be updated. We handle
// ...this separately.
// /////////////////////////////////////////////////////////////////////
if ($this->scenario == self::SCENARIO_LOGIN)
{
/** Login scenario */
$this->last_login = new CDbExpression('NOW()');
}
if ($this->scenario == self::SCENARIO_ACTIVATION)
{
/** Account activation scenario */
if ($this->activation_status == 'activated')
{
$this->activation_code = '';
$this->status = 'active';
$this->activation_time = new CDbExpression('NOW()');
}
}
if ( ($this->scenario == self::SCENARIO_CHANGE_PASSWORD) ||
($this->scenario == self::SCENARIO_REGISTER) ||
($this->scenario == 'insert') ||
($this->scenario == 'update')
)
{
/** Password change scenario */
// /////////////////////////////////////////////////////////////////////
// Encrypt the password. Only do this if the password is set
// /////////////////////////////////////////////////////////////////////
if (isset($this->password) && (!empty($this->password)))
{
$this->password = CPasswordHelper::hashPassword($this->password);
}
}
/** All other scenarios */
// /////////////////////////////////////////////////////////////////////
// Set the create time and user for new records
// /////////////////////////////////////////////////////////////////////
if ($this->isNewRecord) {
$this->created_time = new CDbExpression('NOW()');
$this->created_by = '1'; // Special case for not logged in user
$this->modified_by = '1';
}
else
{
$this->modified_by = isset(Yii::app()->user->id)?Yii::app()->user->id:1;
}
// /////////////////////////////////////////////////////////////////////
// The modified log details is set for record creation and update
// /////////////////////////////////////////////////////////////////////
$this->modified_time = new CDbExpression('NOW()');
return parent::beforeSave();
}
Notice that I have full access to the record BEFORE the save happens (ie. no access to primary-key when a new record is being processed.
Look out also for built in scenarios 'insert' and 'update'.
Note also that I invoke the parent beforeSave before exiting to cascade events in the parents.
Using Custom Events
You can create custom events.
Create an event class eg. protected/components/Newuser.php:
class NewUser extends CModelEvent{
public $userRecord;
}
Then in your controller
$userModel->attachEventHandler('onNewUser',newuserEventHandler);
function newuserEventHandler($event){
// Add custom handling code here
do_some_things_here($event->new, $event->id);
}
In your model, you need to raise the event
$event=new NewUserEvent;
// Add custom data to event.
$event->new=$this->isNewRecord;
$event->order=$this->id;
$this->raiseEvent('onNewUser',$event);
I have created function in laravel helper class to check Authentication in app/lib/Auth.php
class Auto extends \BaseController {
public static function logged() {
if(Auth::check()) {
return true;
} else {
$message = array('type'=>'error','message'=>'You must be logged in to view this page!');
return Redirect::to('login')->with('notification',$message);
}
}
}
In my controller
class DashboardController extends \BaseController {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
Auto::logged();
return View::make('dashboard.index');
}
I expect it redirect to login route if not logged, but it load dashboard.index view with message 'You must be logged in to view this page!'.
How can I redirect to login route with this message?
Why you want to create new helper function for that. Laravel already handle it for you. See app/filters.php. You will be see authentication filter like the following
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
return Redirect::guest('/')->with('message', 'Your error message here');
}
}
});
You can determine if user is Authenticated or not like the following
if (Auth::check())
{
// The user is logged in...
}
Read more about Authentication on Laravel doc.
this should be work :
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
if(Auto::logged()) {
return View::make('dashboard.index');
}
}
I am trying to create a simple login using Yii Here is my auth controller
class AuthController extends Controller
{
/**
* Declare class-based actions.
*/
public function actionLogin()
{
$model = new LoginForm;
$post = Yii::app()->request->getPost('LoginForm');
// If form is submitted
if($post) {
$identity = new UserIdentity($post['username'], $post['password']);
echo $identity->testing();
if($identity->authenticate()) {
echo 'yes';
} else {
echo 'no';
}
exit;
}
$this->render('login', array('model' => $model));
}
}
And here is my UserIdentity
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{ echo 'testing';
$user = LoginForm::model()->findByAttributes(array('username' => $this->username));
if(is_null($user)) {
%this->errorCode=self::ERROR_USERNAME_INVALID;
} else if($user->password != $this->password) {
$this->errorCode=self::ERROR_PASSWORD_INVALID;
} else {
$this->_id = $user->id;
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
function getId()
{
return $this->_id;
}
}
I have mentioned echo 'yes' and echo 'no' but both are not displaying. How to correct it
Well first of all, you won't even see those echo statements, the only things that are rendered visually for an end-user to see in Yii are the "views". For my login code, which is just a little bit different from yours, after confirming authentication, my app is redirected to home page. Your custom UserIdentity file looks fine, but again, that echo statement won't even be seen. This UserIdentity file is just for performing custom user authentication behind the scenes.
In my UserController (as opposed to your AuthController), my actionLogin is:
public function actionLogin()
{
$model=new LoginForm;
// if it is ajax validation request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login())
{
$this->redirect(Yii::app()->user->returnUrl);
}
}
$this->render('/user/login',array('model'=>$model));
}
From the above, for example, you could redirect to the previous page you were at or redirect to your main site view at "/site/index" and under that have some code that does some arbitrary functions or print out HTML depending on if you're logged in or not. An overly simple site view example:
<?php
/* #var $this SiteController */
if (Yii::app()->user->isGuest)
{
// Do stuff here if user is guest.
echo 'User is a guest.';
}
else
{
// Do stuff here if user is authenticated.
echo 'User is authenticated.';
}
?>
<?php
class PI_Controller_Plugin_AssetGrabber extends Zend_Controller_Plugin_Abstract
{
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
/*
The module name
*/
$moduleName = $request->getModuleName();
/*
This modules requires the user to be loggedin in order to see the web pages!
*/
$loginRequiredModules = array('admin');
if (in_array($moduleName,$loginRequiredModules)) {
$adminLogin = new Zend_Session_Namespace('adminLogin');
if (!isset($adminLogin->loggedin)) {
/*--------------------------------------
Here I want to redirect the user
*/
$this->_redirect('/something');
}
}
}
}
I'm trying to do a redirect $this->_redirect('/something') but doesn't work! Do you know how can I do a redirect in this case?
Best Regards,
... rest of code
if (!isset($adminLogin->loggedin)) {
$baseUrl = new Zend_View_Helper_BaseUrl();
$this->getResponse()->setRedirect($baseUrl->baseUrl().'/something');
}
... rest of code
<?php
class AlternativeController extends Zend_Controller_Action
{
/**
* Redirector - defined for code completion
*
* #var Zend_Controller_Action_Helper_Redirector
*/
protected $_redirector = null;
public function init()
{
$this->_redirector = $this->_helper->getHelper('Redirector');
}
public function myAction()
{
/* Some Awesome Code */
$this->redirector('targetAction', 'targetController');
return; //Never reached!
}
}
You need to get the redirector helper, then you can define the targetAction and targetController with the redirector. That should do it.
Either use Zend_Controller_Action_HelperBroker to get the redirect helper or do the redirect directly from the Request object.
See the examples given in
Redirect in Front Controller plugin Zend