I have written a basic login script and now need to update the data stored in the auth component and then save it to the database, this is what i have so far;
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
$this->Auth->user()->last_activity = date("Y-m-d");
$this->Users->save($this->Auth->user());
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Email or password is incorrect, please try again.'));
}
}
I've tried a few different variations but can't get any to work. Any ideas?
Updating data in cakephp3 is slightly different than cakephp2, Try something like this:
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
$userData = $this->Users->get($user['id']);
$userData->last_activity = date("Y-m-d");
if($this->Users->save($userData)){
$user['last_activity'] = $userData->last_activity; // to update auth component
}
// echo $this->Auth->user('last_activity');
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Email or password is incorrect, please try again.'));
}
}
Another way of updating record in cakephp3 is:
$query = $this->Users->query();
$query->update()
->set(['last_activity ' => date('Y-m-d')])
->where(['id' => $user['id']])
->execute();
But I don't recommend this one as callbacks are not fired.
In Cake3, you can take advantage of the afterIdentify event.
In AppController::initialize, add a listener for the event:
\Cake\Event\EventManager::instance()->on('Auth.afterIdentify', [$this, 'afterIdentify']);
Add AppController::afterIdentify function to handle the event:
public function afterIdentify(CakeEvent $cakeEvent, $data, $auth) {
$users_table = TableRegistry::get('Users');
$user = $users_table->get($data['id']);
$user->last_activity = new Cake\I18n\FrozenTime();
// If you ever need to do password rehashing, here's where it goes
if ($this->Auth->authenticationProvider()->needsPasswordRehash()) {
$user->password = $this->request->data('password');
}
$users_table->save($user);
}
Now, the data returned by the Auth->user() call should always be up-to-date without any extra effort on your part.
Related
I am trying to query our database to see if users can log in based on whether the organisation they belong to have logins enabled.
LoginController.php
protected function redirectTo()
{
$user = Auth::user()->id;
$userOrg = UserOrganization::where('user_id', $user)->first();
$org = Organization::where('id', $userOrg->org_id)->first();
if ($org->allow_org_login == 0) {
return '/login';
} else {
if(Auth::user()->has_changed_temp_password == false)
{
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/user/password/change';
} else {
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/overview';
}
}
}
trying to log in as a user belonging to an organisation with allow_org_login = 0 should redirect to the '/login' page, but instead it either logs the user in or prompts for a password change for a new user.
What am I doing wrong?
Edit: Debug contents of $org (allow_org_login on the bottom line)
since there is many to many relation between user and organization.
i suppose this relation is defined in User & Organization as in documentation:
https://laravel.com/docs/7.x/eloquent-relationships#many-to-many
considering that:
user may have more than an organization, and if any of the organization allowed log_in the user should login to your system
$user = Auth::user();
$userOranization=$user->organizations()->get();
$allowUserToLogin=false;
if($userOranization->where('allow_org_login',1)->first()!=null)
$allowUserToLogin=true;
and then:
if ($allowUserToLogin == 0) {
return '/login';
} else { ....
for redirectTo() method it will only fire when we using POST method for login.
inside you redirectTo() method your check condition and then you return '/login';
which it will redirectTo login page. but this time you already login then on login it will check if user login then it redirectTo url that we config on LoginController and protected $redirectTo; it will not call redirectTo() method. cuz this time we use redirect using GET method not POST.
if you want to put validate on redirectTo() method you can try below code:
protected function redirectTo()
{
$user = Auth::user()->id;
$userOrg = UserOrganization::where('user_id', $user)->first();
$org = Organization::where('id', $userOrg->org_id)->first();
if ($org->allow_org_login == 0) {
Auth::logout(); // logout user before redirect
return '/login';
} else {
if(Auth::user()->has_changed_temp_password == false)
{
// depend on you choice need to logout or not
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/user/password/change';
} else {
// depend on you choice need to logout or not
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/overview';
}
}
}
but for my option i will create new middleware for handle this.
I am currently new to Laravel. This is my fist time building with this framework. I 'm trying to create a login. It was easy by running the php artisan make:auth command however i'm trying to determine if the user that was login is regular user or admin?
$table->boolean('is_admin')->nullable();
I've tried to add that to my user model to determine if user is admin or not and try to modify my LoginController by adding this code.
public function determineTypeLogin(Request $request)
{
$user = auth()->user()->is_admin;
if ($user == 1) {
return "admin";
}
return "not admin";
}
however no luck.. Please help
Please check this
public function determineTypeLogin(Request $request)
{
$user = Auth::user()->is_admin;
if ($user == 1) {
return "admin";
}
return "not admin";
}
I think no need to check $user == 1 it return only tru or false so you can dirctly check like
public function determineTypeLogin(Request $request)
{
$user = Auth::user()->is_admin;
if ($user) {
return "admin";
}
return "not admin";
}
I need to check if a user is existing in the mgrUser table. now the propblem is the controller is in the adminController while the model is in the mgrUserModel. how do i use Auth for this? Thats the reason why I made a generic login code.
public function login() {
// if ($this->Auth->login()) {
// return $this->redirect($this->Auth->redirectUrl());
// }
// $this->Flash->error(
// __('Username ou password incorrect')
// );
//since the model is in a different view, I needed to includ the mgrModel and create a generic login
//will revamp the code to fit the built in Aut code for php cake
if(isset($_POST['submit'])) {
$User_ID = htmlspecialchars($_POST['user_id']);
$Pass = htmlspecialchars($_POST['pass']);
try {
$mgrUserModel = new MgrUser();
$isValid = $mgrUserModel->find('first', array(
'conditions' => array("user_id" => $User_ID)
));
if($isValid != null){
if (($isValid['MgrUser']['pass']) == $Pass) {
//this doesnot work
$this->Auth->allow();
$this->redirect($this->Auth->redirectUrl());
}
else{
}
}
} catch (Exception $e) {
//echo "not logged in";
}
// this echo will show the id and pass that was taken based on the user_id and pass that the user will input
//for testing only
// echo $isValid2['MgrUser']['id'];
// echo $isValid2['MgrUser']['pass'];
}
}
You need double == to compare things,
function checkMe()
{
if($user == 'me'){
$this->Auth->allow('detail');
}
}
what you did was assign "me" string to variable $user which always returns true because assignment was possible
Anyway you should use it in beforeFilter which is running before every action from this controller, which makes much more sense
public function beforeFilter() {
parent::beforeFilter();
if($user == 'me'){
$this->Auth->allow('detail');
}
}
the Auth component could be configured to read the user information via another userModel (The model name of the users table). It defaults to Users.
please consult the book for appropriate cakephp version: https://book.cakephp.org/3.0/en/controllers/components/authentication.html#configuring-authentication-handlers
I have a login function in CakePHP 2.7 that seems like it should be split up into two parts. One conditional to handle a first time login with token authentication and then another conditional to handle cases when the user is already logged in. I tried putting the following block in an else statement below the very first if conditional but that threw all sorts of errors.
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again'));
}
Would there be any relatively easy way to separate this function into an if and an else or elseif statement to handle both of those cases with the token authentication?
Login() and beforeFilter() from user controller:
function beforeFilter() {
$this->Auth->allow('check_login', 'index', 'wsdl', 'admin_wsdl', 'admin_service');
parent::beforeFilter();
}
function login() {
echo 'login function';
print_r($this->data);
if (!empty($this->data) && $this->Auth->user()) {
echo 'if statement true';
// Delete all old tokens
$this->Tour->recursive = -1;
$this->Tour->deleteAll(array('Tour.userid' => $this->Auth->user('userid')));
// Create a new token
$this->Tour->create();
$this->Tour->save(array('token' => md5(rand()), 'userid' => $this->Auth->user('userid')));
// Update login count
$user = $this->User->read(null, $this->Auth->user('userid'));
$user['User']['logincount']++;
$this->User->saveField('logincount', $user['User']['logincount']);
// Update last login time
$this->User->saveField('lastlogin', date('Y-m-d h:m:s'));
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again'));
}
}
}
beforeFilter() in the app controller:
function beforeFilter() {
$this->setLayout();
if ($this->Session->check('Auth.User.userid')) {
$tour = $this->Tour->findByUserid($this->Session->read('Auth.User.userid'));
$user = $this->Auth->user();
$tour = $this->Tour->findByUserid($user['User']['userid']);
$user['Tour'] = $tour['Tour'];
$this->set('user', $user);
}else if (isset($_GET['token'])) {
$tour = $this->Tour->read(null, $_GET['token']);
if ($tour) {
$tour['Tour']['sessionmodified'] = date('Y-m-d H:i:s');
$this->Tour->save($tour);
$this->set('user', $tour);
}
}
}
i want to add record to a new user right after regeneration complete the problem that i get the user->id with null value after calling user->save() .
Here is my code
public function register(){
$input=Input::all();
$rules=array(
'username'=>'required|unique:bradoseusers|alphaNum|min:2',
'email'=> 'required|unique:bradoseusers|email',
'password'=>'required|alphaNum|min:6'
);
$v=Validator::make($input,$rules);
if($v->passes())
{
$password=$input['password'];
$password=Hash::make($password);
$user=new Bradoseusers();
$user->username=$input['username'];
$user->Email=$input['email'];
$user->password=$password;
$user->save();
return Redirect::to('login');
}
else
{
return Redirect::to('/Register')->withErrors($v);
}
}
You may try something like this:
public function register()
{
$input=Input::all();
$rules=array(...);
$v = Validator::make($input,$rules);
if($v->passes()) {
$user = new Bradoseusers;
$user->username = $input['username'];
$user->Email = $input['email'];
$user->password = Hash::make($input['password']);
$user->save();
// probably you want to redirect to
// default landing page for logged in user
return Redirect::to('login'); // i.e /dashboard or /
}
else {
return Redirect::to('/Register')->withErrors($v)->withInput();
}
}
the problem was that i have set in the model the primaryKey property to "Email" . So that would override the primary key value so you wouldn't have an "id" field.