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
Related
I have created a log in form for my admin pages and it works, but for now everyone who logs in can access those pages.
My users are also belong to usergroups and my users table in the database has a group_id column. The admin group has an id of 1.
What I'd like to do is that if someone who belongs to the admin group logs in can access the admin pages, but if the user belongs to a different group and tries to log in be redirected to main page or anywhere.
What I'm trying to do is add a similar code to the admin pages controllers
class Dashboard extends MY_Controller {
public function __construct() {
parent::__construct();
// Access control
if(!$this->session->userdata('logged_in')) {
redirect('admin/login');
}
}
}
My model
class Authenticate_model extends CI_Model {
public function login_user($username, $password){
//Secure password
$enc_password = md5($password);
//Validate
$this->db->where('username',$username);
$this->db->where('password',$enc_password);
$result = $this->db->get('users');
if($result->num_rows() == 1){
return $result->row();
} else {
return false;
}
}
}
You can do it yourself, provide validation and set $SESSION variable to retrieve if the user is logged in. But this is too much work, and error prone.
I recommend you to use this popular library: https://github.com/benedmunds/CodeIgniter-Ion-Auth. It is really easy to set up, you just need to copy some files and you are ready to go.
If you really want to do it your self(thats the question) then you need to store in SESSION two variables - logged_in and is_admin.
I would recomend two create library with function:
function is_logged_in($admin = FALSE){
$is_logged = $this->session->userdata('logged_in');
if($admin){
$is_logged = $this->session->userdata('is_admin')
}
return $is_logged;
}
This assumes that you store two booleans "logged_in" and "is_admin" in SESSION.(If user has group_id = 1 then you would store TRUE in is_admin)
Then you can protect your site members only pages
if(!$this->your_authenticatation_library->is_logged_in()){redirect('notMembersControler')}
and admin page:
if(!$this->your_authenticatation_library->is_logged_in(TRUE)){redirect('notMembersControler')}
Thats the basic idea, you need to work around depending on what you are up to. Hope this helps!
I've got a small problem with my smarty project, logout problem to be precise. I have a index.php page which is the "main" page and it gets POST data and directs actions based on current data. There`s checking if the session variables has been set. Now when I login I have function like this:
function login($value)
{
$res = $this->sql->checkLogin($value);
if($res)
{
//checks if user is admin
$isadm = $this->sql->isAdm($value);
if($isadm == true)
{
$_SESSION['user'] = $value['name'];
$_SESSION['adm'] = true;
$message = 'Admin';
$this->tpl->assign('var', $message);
if($_SESSION['adm'] == true)
{
//sets some variables for admin users
$navigation = 'navi';
$this->tpl->assign('navigation', $navigation);
}
$this->tpl->display('maint_main.tpl');
}
//user is not admin
else
{
$_SESSION['user'] = $value['name'];
$_SESSION['adm'] = false;
$message = 'Perus';
$this->tpl->assign('var', $message);
if($_SESSION['adm'] == true)
{
$navigation = 'navi';
$this->tpl->assign('navigation', $navigation);
}
$this->tpl->display('maint_main.tpl');
}
}
//login failes, show login form and info
else
{
$message = 'Login failed';
$this->tpl->assign('var', $message);
$this->tpl->display('login_form.tpl');
}
}
and logout function :
function logout()
{
setcookie(session_name(), '', time()-42000, '/');
session_unset();
session_destroy();
$this->tpl->display('login_form.tpl');
}
These work just about the way they are supposed to but the real problem occurs when I log out and redirect to the login_form.tpl. If I use the back button of the browser the POST data with username and password is retrieved and the login goes through again. This causes that those pages behind login are still viewable. As I am not quite familiar with Smarty yet I couldn`t figure out any way to fix this. So basically how to prevent access to that POST data after logout?
I don't think this has anything to do with smarty. This is a browser/http generic issue. Most browsers will re-post form data after confirmation from the user.
One approach to make re-posts of the form invalid would be to pass along a secret code/token (perhaps a guid or your session id) which is also stored in session data. When the user logs out, clear their session (or at least the secret code you're checking). When the user logs in, check to make sure that the confirmation code matches the one for the current session.
This pattern is often used to manage csrf attacks and is often known as a 'synchronizer token'. This blog post provides a good explanation https://blog.whitehatsec.com/tag/synchronizer-token/
I recently built my first web application using laravel and overall it has been great. I have picked up the framework very easily except for this one issue. I am trying to use the framework's built in authentication. I am able to log in my users for a given request but I am trying to implement the remember me functionality by the Auth::attempt() method passing in true as the second parameter as per the documentation.
I have been trying this method for many hours without any luck. I have seen a video at this url (https://www.youtube.com/watch?v=hYUf6u_txhk#aid=P-a-d6RlOC8) which shows which cookie is set when a user is remembered in the application and this cookie is not being set in my browser when I try to remember my user. The cookie is not being set and my users are not being remembered. Here is my code.
if (Auth::attempt(array('email' => Input::get('email'), 'password' => Input::get('password')), true))
{
$userid = DB::table('users')->where('email', '=', $userdata['email'])->pluck('id');
Auth::login(Auth::user());
if (Auth::check())
{
echo "LOGGGEED IN WOOOOOOO";
}
else {
echo "user not logged in";
}
return Redirect::to('/dashboard/' . $userid);
}
Before the redirect happens here is the page I see
Here is the controller that handles the redirect.
class DashboardController extends BaseController
{
public function showDashboard($userid)
{
if (Auth::viaRemember())
{
echo "WOOOOOOOOOOOOOOOO";
}
else {
echo 'booooooo';
}
if (Auth::check())
{
echo 'YAY LOGGED IN';
}
else {
echo 'BOO AGAIN';
}
$user = User::where('id', '=', $userid)->first();
$subscriptions = $user->subscriptions;
$orders = $user->orders;
return View::make('dashboard', compact('user', 'subscriptions', 'orders'));
}
}
But when the redirect happens and /dashboard/{userid} is loaded you can see in the top left hand corner that my echo statements show the user is not being remembered!
I am so frustrated at this point since this is the last step I need to finish my application and I am embarrassed that the laravel documentation says "Laravel aims to make the implementation simple". I have the entire rest of my application working EXCEPT for this part so I would appreciate any and all help with this issue! If you need anymore information please feel free to ask me.Dashboard page
SOLUTION:
In app/config/session.php in the array my 'driver' key had a value of 'file'. After switching this to 'cookie' everything worked as expected.
I am using codeigniter on my project, and I have a login module and I authenticate each module. When the session does not exist then redirect to the login page. So, this works but sometimes it may happen when I login and then refresh the page I get redirected to the login page (meaning the session is gone).
Please do not try to tell me to use another library such as php native etc. I just want to know what the problem causing this is.
function _admin_login()
{
$this->form_validation->set_rules($this->login_rules);
$data['title'] = "Login";
$data['form_url'] = $this->uri->uri_string();
$data['login_btn'] = form_submit('login','Sign In','class="btn btn-large btn-block btn-primary"');
if($this->form_validation->run($this) == FALSE){
$data['user'] = form_input('username','','class="input-block-level input-large" placeholder="Username"');
$data['passw'] = form_password('password','','class="input-block-level input-large" placeholder="Password"');
$this->template->set('title','Login');
$this->template->load('template_login','login_view',$data);
}else{
$username = $this->input->post('username',true);
$row = $this->authentication_model->get_user_info($username);
$this->session->set_userdata('user',$row['user_id']);
$this->session->set_userdata('username',$row['username']);
$this->session->set_userdata('login_state',true);
$this->authentication_model->update_last_login();
redirect('product');
}
}
This is my login script, if the validation passes then the session is set... and in every controller I have checked the session script. Example below:
$this->authentication_plugin->check_logged_in();
function check_logged_in()
{
if(logged_in() === FALSE){
set_alert('Login in to view this page!!','error');
set_bookmark('login_url');
redirect("login");
}
}
function logged_in()
{
$CI =& get_instance();
$user = $CI->session->userdata('user');
if(!$CI->load->library('session')){
echo "no session is loaded";
die;
}
if(!empty($user)){
return true;
}else{
return false;
}
}
Any ideas? Thanks!
autoload the session library and remove that from your login script.
In config/autoload.php look for $autoload['libraries']
add 'session'
in config/config.php
scroll down to cookie configs and look for $config['sess_cookie_name']
make sure there is no underscore in the cookie name. you have to change the codeigniter default name to do this.
test by doing session checks in the constructor. its a quick sanity check to see if the sessions are working or not.
I'm developing a basic web app using the MVC architecture. I'm building my own to try and fully understand how the MVC arch works so this doubles as a learning exercise.
I am using the Aura Router classes to map my URLs to controllers and action so that something like mysite.com/login will be mapped to LoginController and if I submit a form to mysite.com/login/login it will map it to LoginController->doAction('login').
Example of a controller looks like this:
class LoginController implements iController {
public function doAction( PDO $dbh, $action ) {
switch( $action ) {
case 'login':
//login here
$user = new User();
$user_id = FALSE;
if( $user_id = $user->login( $_POST['email'], $_POST['password'] ) ) {
//save user id to session
}
else {
$results = array( 'errors' => array( 'invalid' ) );
MembershipFunc::redirect( '/login', $results );
}
break;
case 'logout':
//logout
break;
default:
break;
}
}
}
The problem I am facing is that to avoid people from refreshing the page and resubmitting the data I like to forward the user back to the login page if the login failed. Currently if I don't forward them then they would appear on the page mysite.com/login/login and I don't think it's particularly clean. It's okay for my simple login form because an error could redirect to mysite.com/login?error=email,password&email=user#domain.com but in the case of a huge form then I would get a huge URL query which is really gross.
I have scoured for good resources with basic (yet useful) PHP code examples on how MVC works and I've struggled to find anything particularly useful. Should I avoid mapping my URL structures to an action and instead opt for putting a POST field called "action" instead? Should I somehow build a system where I pass this data through an array in the SESSION data?
Any advice?
Note: I would just like to specify that I know this question doesn't fit in the SO culture because it might not have a right/wrong answer but I find SO always has the best/most knowledgeable user-base. If anyone has tips as to where I should direct these questions I would really appreciate it so I don't add clutter!
In my MVC URLs look like:
index.php?c=Controller&m=ControllerMethod&d=slash/sepparated/list/of/stuff
Data (d=) is exploded on the slashes and passed as an array to every controller method.
Autoloading (via spl_autoload_register()) is used to call the class (c=) and then the method in that class (m=).
Also, it sounds like you're either not setting the ACTION on your form or you're deliberately setting the ACTION to GET. As a general rule, ACTION should be POST to keep the URLs sane. Except search forms. Those can be GET with various advantages.
Re-directing to prevent a resubmitted form on refresh is your best option (probably only option). But in my MVC index.php?c=user&m=login handles both the login page and the login action.
Example
class login extends Controller {
public function login($data) {
if(empty($_POST)) {
$this->view = "login.tpl";
return TRUE;
}
$res = $this->model->auth();
if($res !== TRUE) {
$_POST = NULL;
$this->errorState = 1;
$this->errorMsg = "Invalid login details";
$this->login();
return FALSE;
}
Core::setMessage('success', 'user', 'login', '2', 'Logged in successfully');
$home = new home(); //whatever the main controller is
$home->index($data);
//alternatively you can redirect
header("Location: index.php?c=home&m=index);
return TRUE;
}
}
Does this make sense or have I completely missed the mark?