I am doing project using zend framework-2. I want to restrict access to certain web directories through URL(if user without log in). if user tried to log in I need to redirect login page. this is what I do(rough idea not codes ).
AuthController
if(username and password ok){
setcookie('username', $username);
setcookie('password', $password);
//redirect to AlbumController indexAction
return $this->redirect()->toRoute('album', array('controller' => 'album', 'action' => 'index'));
}
so within AlbumControoler I added this code
public function indexAction()
{
if(isset ($_COOKIE['username']) && isset ($_COOKIE['password'])){
//some codes
}
else{
//if user not logged redirect to loogin page
return $this->redirect()->toRoute('auth', array('controller' => 'auth', 'action' => 'index'));
}
}
so if I use this way I need to add above codes every action. so my question is is this way ok? or is their easy way to do that?
As an answer for the actual question, you can do it in your controllers construct... something like this...
namespace Application\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class IndexController extends AbstractActionController {
public function __construct() {
$session = new \Zend\Session\Container('auth');
if ( !isset($session->name) || !is_string($session->name) ) {
echo "The following is not set:".$session->name;
header('Location: /user/login');
exit();
}
}
But as the previous posters noted cookies are really bad to use for something like this. This is a very generic example although the exit(); part is pretty important in this sense as you want to kill the script to not show any data in case the user hits escape on their browser. The exit(); will essentially kill out and not display anything.
Related
My Phalcon application has a layout with another layout inside of a div element of the main layout. My problem is that when the session time's out the login form (session/index) appears in the second layout. Here's a visual and the code that checks if the session is still active. I know what is happening. Just can't find a solution that preforms my desired action. Thanks.
<?php
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\Dispatcher;
class ControllerBase extends Controller
{
protected function initialize()
{
$this->tag->setTitle('Website | ' . $this->view->H1Tag);
$this->flash->output();
}
public function beforeExecuteRoute(Dispatcher $dispatcher)
{
if (!$this->session->has('auth') && $dispatcher->getControllerName() != 'session') {
$dispatcher->forward(['controller' => 'session', 'action' => 'index']);
return false;
}
}
}
You might have to inject JS in your script: before redirecting to the login page, something like:
<?php echo "<script>window.top.location.href = \"http://www.yourdomain/login\";</script>"; ?>
As a server-side language, PHP can't escape the iframe by itself.
How do I change the content for a user when he logs in? I mean like enabling voting, changing "login" to "logout" etc.
What I think to do is to start the session when user logs in (I am preferring to start session only when user logs in, not all the time). Then add data to the session's cookie like-
//controller
$moredata = array(
'username' => $this->username,
'login' => TRUE
);
$this->session->set_userdata($modedata);
//redirect
Then in the other controller, where he has been redirected I check the following-
$login = $this->session->userdata('login');
if ($login==TRUE)
Depending on the 'if' condition I will pass a variable to the view, with the help of that variable I will forward only the div/sections which should be shown to a logged-in user.
The problem is, while performing the above comparison Codeigniter shows following error (remember I haven't added 'session' in autoload array yet)
Message: Undefined property: NameOfController::$session
And If I set following in the autoload file
$autoload['libraries'] = array('session');
then the "if ($login==TRUE)" comparison always shows FALSE.
What should I do?
If I were you, I'd place all your session checks in a base controller which all your other main controllers extend. This allows you to keep things DRY:
class BaseController extends CI_Controller {
public function __construct()
{
parent::__construct();
}
public function isLoggedIn()
{
// Will return true or false
return $this->session->userdata('login');
}
}
And in one of your functional controllers (the example below handles users):
class UserController extends BaseController {
public function __construct()
{
parent::__construct();
}
public function profile()
{
// Redirect if not logged in
if (!$this->isLoggedIn()) {
$this->redirect('some/other/page')
}
}
public function register()
{
// Show different HTML if not logged in
$data = array(
'isLoggedIn' => $this->isLoggedIn()
);
$this->load->view('register', $data);
}
}
The second method in UserController allows you to render different content in your view:
<? if ($isLoggedIn): ?>
<p>You're logged in!</p>
<? else: ?>
<p>Not logged in</p>
<? endif; ?>
On my last project we created a simple permissions helper that had functions to check for logged-in status and for privilege levels. Then we'd just call the helper's functions as needed from anywhere in the system. If the user is logged in and has privs for that content then they get the content - otherwise we'd redirect them to a registration or other error page. Since all of that logic is in the helper functions, we could wrap any permission-requiring code in a quick permissions call like if(is_logged_in()){code requiring login to access}.
I am using zend framework. I have built a simple login screen. when the user logs in, I want to set a session and then in the init function of the member area controller its meant to check for the session and grant access, else, redirect to login screen.
I have set my login controller like so, this check the username and password and sets the session:
if (isset($_POST['loginSubmit']) && $form->isValid($_POST)){
$inputtedUsername = $_POST['username'];
$inputtedPassword = $_POST['password'];
if ($inputtedUsername == $username && $inputtedPassword == $password) {
$loggedIn = new Zend_Session_Namespace('loggedIn');
$loggedIn->success;
$this->_forward('index', 'home');
} else {
echo 'invalid';
}
}
I have a home controller, which only logged in users should be able to see, so in the innit function I have:
$loggedIn = new Zend_Session_Namespace('loggedIn');
if (isset($loggedIn->success)) {
echo 'success';
}else{
$url = $this->view->url(array(
'controller' => 'index',
'action' => 'index'));
header('Location:' . $url);
}
}
when i log in, using the correct credentials, it redirects me to login screen as stated in the else function.
what am i doing wrong?
First your use of Zend_Session_Namespace is incomplete (you never assigned a value to the namespace):
$loggedIn = new Zend_Session_Namespace('loggedIn');//here you created a namespace
$loggedIn->success;//here you created a key in that namespace with no value
The way your code seems to be structured any value assigned to $loggedIn->success would return true, so maybe try :
$loggedIn = new Zend_Session_Namespace('loggedIn');//here you created a namespace
$loggedIn->success = true;
While this might fix your current issue, I want to suggest you take a look at two Zend components that can really help with authentication and authorization.
The first is Zend_Auth, a component that deals with application authentication and will also help handle user session persistence. Rob Allen has a tutorial to help get you started.
The second is Zend_Acl, The Access Control List component, deals with authorization, who has access to what. A place to start with Zend_Acl
I want to protect certain methods in my application such as publish, unpublish, and close. By protection I don't mean user authorisation but rather the ability to call the method in a certain way.
I have thought about FORCING the methods to be called using POST rather than GET so that a person can't just paste the URL in the address (even though I could just check the user id of the person doing it). However this means wrapping each button in a different form for each method call.
Alternatively I could use a GUID to allow the GET method but make sure it only allows the correct person to do the function.
Any thoughts ideas on this?
So far I have tried:
function publish($id = null)
{
$post = $this->Post->find('first',array('conditions'=>array('Post.id'=>Tiny::reverseTiny($id))));
if ($this->request->is('post') || $this->request->is('put'))
{
$this->Post->id = $post['Post']['id'];
$this->Post->saveField('status', 1);
$this->Session->setFlash('Your post has been published!');
$this->redirect(array('controller'=>'posts','action'=>'view','id'=>Tiny::toTiny($post['Post']['id'])));
}
else
{
die('GET METHOD NOT ALLOWED');
}
}
But as stated above that means the link/button for this method would need be in a form containing the action call to this method. And If I have several methods I would need several forms...
Cheers
One way I have thought about is allowing the get method and then checking the user id of the post compared with the logged in user id like so:
if ($this->request->is('get'))
{
if($post['Post']['user_id'] != $this->Auth->user('id'))
{
$this->Session->setFlash('You don\'t have permission to edit that post!');
$this->redirect(array('controller' => 'posts', 'action' => 'index'));
}
else
{
$this->Post->id = $post['Post']['id'];
$this->Post->saveField('status', 1);
$this->Session->setFlash('Your post has been published!');
$this->redirect(array('controller'=>'posts','action'=>'view','id'=>Tiny::toTiny($post['Post']['id'])));
}
}
Is this good practice?
(Assuming CakePHP 2.0 here)
Firstly, rather than calling die on a Post/Get check. Throw an exception, exceptions in cake are wonderful (Exceptions):
if (!$this->request->is('get')) {
throw new MethodNotAllowedException();
}
Cake also provides a way to generate a link to delete (via post) in your template.
<?php echo $this->Form->postLink('Delete',
array('action' => 'delete', $post['Post']['id']),
array('confirm' => 'Are you sure?'));
?>
Edit (Link): postLink
This is my first answer in a Stack Overflow. Hope it was helpful.
It sounds like you need ACL or some form of permissions if you want to only allow certain users to perform the function. The reason you wouldn't use something like you have posted ( if($post['Post']['user_id'] != $this->Auth->user('id')) ) is because you will end up replicating that code in a lot of functions through out your code base. That is very sloppy.
However, you only want to make sure that the submission was submitted in a specific manner, then the throw error method is the way to go. And you should be able to keep the submission inside the same function like so:
public function publish($id = null) {
if (!$id || !$this->request->is('get') || !$this->request->is('post') || !$this->request->is('put')) {
throw new MethodNotAllowedException();
}
if ($this->request->is('post') || $this->request->is('put')) {
$this->Post->id = $post['Post']['id'];
$this->Post->saveField('status', 1);
$this->Session->setFlash('Your post has been published!');
$this->redirect(array('controller'=>'posts','action'=>'view','id'=>Tiny::toTiny($post['Post']['id'])));
}
if ($this->request->is('get')) {
// perform your get request here
}
}
With minimal code
$this->request->allowMethod('post');
I want to make some actions available only for logged in users.
I've tried to restrict some by this code:
function _remap($method)
{
$restricted = array('update_rating', 'delete_post');
if( ! $this->session->userdata('logged_in') && in_array($method, $restricted))
{
echo 'Log in, please';
}
else {
$this->$method();
}
}
But $this->$method() didn't receive parameters which was sent in url. What to do?
I want to make some actions avalible only for logged in users.
To restrict logged in users for an entire controller use something like:
function __construct(){
if(!is_logged_in){
redirect('user/login');
}
}
Or do the same if you need to restrict a specific method:
function restricted_function(){
if(!is_logged_in){
redirect('user/login');
}
}
This requires that you have an is_logged_in variable set before the controller is called.
I use a a MY_controller that checks for a logged in session that all controllers inherit.
Ideally you should not be using this patter of development for creating a user login. You should simply do the check in the constructor of the class that you're calling, and use $this->router->method to see what method the user is trying to access. Check that against an array of methods that require login, then check to see if the user is logged in or not. If one of the conditions is false, redirect to login page, or else, continue with execution of the call. Sample implementation below:
Class XYZ extends Controller{
function __construct() {
parent::controller();
$protected_methods = array('method_1', 'method_2');
if(in_array($this->router->method, $protected_methods)){
// check if user is logged in
if(!$this->session->userdata('logged_in'))
redirect('/login');
}
}
}
You didn't send any parameters to it.
You should give all the parameters you need the $method to evaluate.
function _remap($method)
{
$restricted = array('update_rating', 'delete_post');
if( ! $this->session->userdata('logged_in') && in_array($method, $restricted))
{
echo 'Log in, please';
}
else
{
$params = get_func_get_args();
$this->$method($params);
}
}
Note that the methods would now receive and array of the parameters.