I am writing the following code to logout particular user from Admin System.
I have session table. I am following this link : https://laravel.com/docs/5.2/session
$User = $this->Get($obj);
$UserSession = SessionModel::where('user_id', $obj->UserID)->first();
if($UserSession != null) {
$UserSession->user_id = null;
$UserSession->payload = null;
$UserSession->save();
}
Is it a correct approach to do so?
You can really clean this up in one line of code:
$deleted = SessionModel::whereUserId($obj->UserID)->delete();
// Returns the number of deleted sessions.
return $deleted;
Deleting all session records that belong to a user will log the user out of all sessions they have.
For example, if a user is logged in on your application on their phone and computer, they will be logged out on both devices.
$User = $this->Get($obj);
$UserSession = SessionModel::where('user_id', $obj->UserID)->first();
if($UserSession != null) {
$UserSession->user_id = null;
$UserSession->payload = null;
$UserSession->save();
}
You must noticed that is user can have more session records if user logs in with many different browser
=> Solution: get all rows with given user_id in sessions table and delete them. Use useful Collection method
$User = $this->Get($obj);
// Get Collection Object
$UserSessions = SessionModel::where('user_id', $obj->UserID)->get();
if($UserSession != null) {
// Use each method on Collection Object
$UserSessions->each(function($UserSession){
$UserSession->delete();
});
}
You might consider that the user_id in your Session table should be nullable and have a default null value, since users that are not logged in have no user id. Then your migration might have this line.
$table->integer('user_id')->unsigned()->nullable()->default(null);
Then deleting the row of a specific user in this table would delete that users session.
Related
I've set up a log in process where a verification code is generated, and when successful, is then removed. However, i want to make sure that if there's multiple verification codes for the same user, upon log in success, delete all records for that user.
Here's my code
if ($model->validate() && $model->login()) {
//delete this verification code
$verificationCode->delete();
//delete all existing codes for user_id
VerificationCode::model()->deleteAll('user_id',$user->id);
Yii::app()->user->setReturnUrl(array('/system/admin/'));
$this->redirect(Yii::app()->user->returnUrl);
}
However, this seems to just delete all the records, regardless on different user_id's in table. Can anyone see where I'm going wrong?
If you want to delete record with specified attributes, the cleanest way for this is to use deleteAllByAttributes():
VerificationCode::model()->deleteAllByAttributes(['user_id' => $user->id]);
Seems you call the function delete() in wrong way ... try passing value this way
VerificationCode::model()->deleteAll('user_id = :user_id', array(':user_id' => $user->id));
For Yii2, the documented way is to use the function deleteAll().
I normally pass the arguments as an array, like so:
VerificationCode::deleteAll(['user_id' => $user->id]);
Also, you can use the afterDelete method, to make sure that everytime or everywhere someone deletes one verificationCode, your application will also delete every userVerificationCode. Put this in your verificationCode model class:
protected function afterDelete()
{
parent::afterDelete();
VerificationCode::model()->deleteAll('user_id = :user:id',[':user_id' =>$this->user_id]);
//... any other logic here
}
You can use below method for deleting all user_id entry from database:
$criteria = new CDbCriteria;
// secure way for add a new condition
$criteria->condition = "user_id = :user_id ";
$criteria->params[":user_id"] = $user->id;
// remove user related all entry from database
$model = VerificationCode::model()->deleteAll($criteria);
or you can use another method directly in controller action
VerificationCode::model()->deleteAll("user_id= :user_id", [":user_id"
=>$user->id]);
use below method for redirecting a URL
$this->c()->redirect(Yii::app()->createUrl('/system/admin/'));
After registration i need to redirect to user dashboard directly. I need to set session based on user role and last registered id. how to set this. already i have setsession function auth_model.php based on this i need to setsesion
function setUserSession($row=NULL)
{
switch($row->role_name)
{
case 'owner':
$values = array('user_id'=>$row->id,'logged_in'=>TRUE,'role'=>'owner');
$this->session->set_userdata($values);
break;
case 'employee':
$values = array('user_id'=>$row->id,'logged_in'=>TRUE,'role'=>'employee');
$this->session->set_userdata($values);
break;
}
}
i am doing registration using ajax and redirect using windows.location.href= "dashboard.php"
we need to setsession when we get the success status in php file. we need to set the session
$this->session->userdata('last_generated_id')
select * from users where user_id = $this->session->userdata('last_generated_id')
$row = $this->db->result();
$this->auth_model->setUserSession($row);
redirect('logged_in_page');
I found some similar question 1 year ago: Codeigniter Tank Auth add folder upon registration... but not with username included.
I tried to add username (of the registered person in that moment) in module, function create_user.This function create new folder with $user_id and _ like: 1_ but without username of the registered person. I tried to include data $username from $data array, but hoplesss...
if($this->db->insert($this->table_name, $data)) {
$user_id = $this->db->insert_id();
$name = $username;
if(!is_dir(FCPATH."./uploads/".$user_id."_".$name)){
mkdir(FCPATH."./uploads/".$user_id."_".$name , 0777);
}
I know that $data array has username on 1. position for DB write purpose. I tried this possiblity: $name = $username; $name = $data[0]; I found that the library, Tank_auth.php has function get_username(). It is for later purpose when the new user will log in...
How can I get username from $data or DB, table users, cell username ?
Try
$name = $data['username'];
in your code to get the name of the user.
From CodeIgniter Active Record manual, $data is an associative array which will have table field names as keys.
From Tank Auth it is clear that users table contains a field with the name username to store the user's name.
Let me know if this helps.
In my web application using codeigniter, I stored role data that I have query from database before in session.
$role = $this->session->userdata('role');
And in every model or controller, i always use this variabel ($role) to manage user behaviour in my web.
Such as
if($role==1)
{
//Behaviour for admin.
}
else if($role==2)
{
//Behaviour for general user
}
else
{
//Do something
}
My problem : If many users login to my system, the session data always lost without click logout before. Thanks.
FOR YOUR INFORMATION :
I have store the role in database, but for easy way the value of role that i've get before, I stored it in session. FOr the easy solution. Thanks.
Store the role in the database in a users table. I have 4 roles in my application student, staff, admin, president.
You then would query the database on the username that was entered,
if the role = 1 then send to the appropriate page.
Sort of like this :
$sql = "SELECT * FROM users WHERE username = :username AND role = 1";
$role = $this->db->conn_id->prepare($sql);
$role->bindParam(':username', $username);
$role->execute();
if ($role) {
if ($role->rowCount() == 1) {
return TRUE;
}
}
then in the controller do
if ($this->yourmodel->yourfunction($yourvariable)) { // Checks if the query above returns TRUE!
redirect(to what ever page you want)
}
When my users log into the website their first name, last name and ID are missing from the session data because my session data is coded to take post data and submit into the session table in my database.
Because user logs in with email and password in my session data only email appears and nothing else does.
How can I make first name, last name and id appear in my session table in my db? I want to some how grab these details from the database when user is logging in and provide it in my $u_data array so it get's posted upload login success.
Here is my code:
<?php
class Login_Model extends CI_Model {
public function checkLogin() {
$this->db->where('email', $this->input->post('email')); //compare db email to email entered in form
$this->db->where('password', $this->hashed()); //compare db password to hashed user password
$query = $this->db->get('users'); //get the above info from 'user' table
if ($query->num_rows() == 1) { //if number of rows returned is 1
$u_data = array( //new variable with session data
'user_id' => $this->db->insert_id(),
'email' => $this->input->post('email'),
'first_name' => $this->input->post('first_name'),
'last_name' => $this->input->post('last_name'),
'logged_in' => TRUE
);
$this->session->set_userdata($u_data); //send data from variable to db session
return TRUE;
} else {
return FALSE;
}
}
public function hashed() { //hashing method
// sha1 and salt password
$password = $this->encrypt->sha1($this->input->post('password')); //encrypt user password
$salt = $this->config->item('encryption_key'); //grab static salt from config file
$start_hash = sha1($salt . $password);
$end_hash = sha1($password . $salt);
$hashed = sha1($start_hash . $password . $end_hash);
return $hashed;
}
}
If you're tracking sessions in your DB, two solutions come to mind.
First, you could select the first/last from the user table and insert it into the session table. This requires changes to your application.
Second, you could set up a view for your application, in which the session table is automatically joined with the appropriate user, but that assumes you already have some unique identifier for which user it is in the session (was that the email address?*). This solution would not require any changes to the application code, but would require changes to the DB, which may be the preferred method depending upon your deployment requirements (or it may not :) ).
* as a side note, if you're using email addresses for unique identifiers, be aware that some people share email addresses as you decide if this is the right solution for you.
It'd be as simple as doing something like:
session_start();
$_SESSION['userdata'] = $u_data;
within your CheckLogin method. The session is just a regular PHP array that happens to be automatically preserved for you. You can put anything you want into it, but you do have do put things into it yourself - PHP won't do it for you.
comment followup:
gotcha. So, you simply modify you class to fetch that information from the DB once the login's authenticated. I don't know how your DB class works, but instead of merely checking if there's a matching row, fetch the first/last name, using a query something like this:
select firstname, lastname
from users
where email=$email and password=$password
If you get a result row, you know it's a valid login, and then you just retrieve the name data. I have no idea how your db class works, but it shouldn't be too hard to get it to do that.
When I'm working with Auth systems in CodeIgniter I have made it a practice to include the "user" object globally in views, and also globally in my controllers, by fetching the userdata in the constructor, like so...
<?php
class My_Controller extends Controller {
private $the_user; //global var to store current user data
function My_Controller() {
parent::Controller();
$data->the_user = $this->ion_auth->get_user(); //get user data
$this->load->vars($data); //load into all views as $the_user "$the_user"
$this->the_user=$data->the_user; //load into private class variable "$this->the_user"
}
At that point $the_user variable object is available in all views by default AND $this->the_user is always available to controller functions. It always represents the user currently logged in.
I am using Ion_auth for authentication and fetching the user, so that piece you would have to fill in.
I actually just constructed a "How-to" to implement extended Controller classes so all the Auth logic is automatically inherited to all "protected" Controllers.
The following solved this issue for me. I looked at one of my old questions on here and used my common sense.
I made this edit to my code.
if ($query->num_rows() == 1) { //if number of rows returned is 1
$user = $query->result();
$u_data = array( //new variable with session data
'user_id' => $user[0]->id,
'email' => $this->input->post('email'),
'first_name' => $user[0]->first_name,
'last_name' => $user[0]->last_name,
'logged_in' => TRUE
);