CakePHP 3 refresh session data - php

I have a page where i can modify user details (username,first name,avatar...).
I have an element in my navbar with informations about the currently logged in user. The thing is I can't figure out how to refresh the session immediately after data is modified.
in UsersController:
public function edit($id = null)
{
if (!$id) {
throw new NotFoundException(__('Invalid user'));
}
$user = $this->Users->get($id);
if ($this->request->is(['post', 'put'])) {
$this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
//REFRESH SESSION ????\\
$this->request->session()->write('Auth.User', $user);
//\\
$this->Flash->success(__('User has been updated.'));
return $this->redirect(['action' => 'edit/' . $id]);
}
$this->Flash->error(__('Unable to update User details.'));
}
$this->set(compact('user'));
}

Just update it the same way as you're setting it when loggin in, ie using AuthComponent::setUser().
Also you may want to do that only in case the user that has been edited, is actually the user that is currently logged in. And you want to set the data in the same format as the Auth component does, that is (for now), as an array, and, for security purposes, without the password.
A simple example that assumes a single column primary key named id, and a password column named password
if ($this->Auth->user('id') === $user->id) {
$data = $user->toArray();
unset($data['password']);
$this->Auth->setUser($data);
}
See also
Cookbook > Controllers > Components > Authentication > Identifying Users and Logging Them In
Cookbook > Controllers > Components > Authentication > Manually Logging Users In

Related

Register user acces in laravel

I have a login in laravel 5 and I need to register in a table the user information when entering the site (ip address, os, browser and timestamp) i have the code and my model to register this.
I have a middelware for this login but when use the function 'handle' this save a record when refresh the browser
Thanks
This is my code
public function handle($request, Closure $next)
{
if(!Auth::guard('web_admin')->check()){
return redirect('admin/login');
}
if(Auth::guard('web_admin')->user()->delete==='0' && Auth::guard('web_admin')->user()->status==='1'){
$browser_data = get_browser($_SERVER['HTTP_USER_AGENT'],true);
//dd($browser_data);
dd($request);
$model = new Access();
$model->ip = $request->ip();
$model->dir_mac = $this->mac() ;
$model->computer = gethostname()."/".$this->operating_system_detection();
$model->browser= $this->navegador();
$model->admin_id =Auth::guard('web_admin')->user()->id;
$model->save();
return $next($request);
}else{
Auth::guard('web_admin')->logout();
return redirect('admin/login');
}
}
When the user login information will be recorded. As a result, use a function after validation and before moving to the home page to receive and store this information. Because the user will try to log in once.

Session doesn't get stored permanently Laravel 5.5

I am creating a small blog-esque site. This site has basically 3 permission levels: Admin (can edit/remove any post AND create a user), a user (can upload posts and pictures) and a guest (no account needed, can just browse the posts).
I am using Laravel 5.5 to create this site.
When someone logs in, after being authenticated, I store their username and user type (admin/user) in a session and after login, they are redirected to their respective pages, as shown in the below code.
I overrided the 'authenticated' method in the AuthenticatesUsers trait:
LoginController.php
protected function authenticated(Request $request, $user)
{
$type = $user->toArray()['type'];//get user type (admin/user)
$username = $user->toArray()['username'];
$request->session()->put('type', $type);
$request->session()->put('username', $username);
if ( $type == 'admin' ) {
return redirect()->route('admin_home');
}
return redirect()->route('user_home');
}
The above code works and my user is redirected upon successful login.
However, if my user accesses the site home (localhost:8000/) I want the user to see the admin home page or user home page (localhost:8000/ just shows the homepage for a not logged in guest)
I did that using the following codes:
Web.php
Route::get('/', 'ContentController#publicHome');
Route::middleware('auth')->group(function(){
Route::get('/user/home', 'ContentController#userHome')->name('user_home');
Route::get('/admin/home', 'ContentController#adminHome')->name('admin_home');
});
Filtering whether user is logged in or just a guest:
ContentController - publicHome function
public function publicHome(Request $request){
$data = [];
$data['home'] = 1;
if($request->session()->has('type')){
switch ($request->session()->pull('type')){
case 'admin':
return redirect()->route('admin_home');
case 'user':
return redirect()->route('user_home');
}
}
return view('public.home', $data);
}
ContentController - userHome function
public function userHome(Request $request){
$data = [];
$data['username'] = $this->getUsername($request);
$data['type'] = $this->getUserType($request);
// dd($data); explanation for this line below
return view('user.home', $data);
}
ContentController - adminHome function
public function adminHome(Request $request){
$data = [];
$data['username'] = $this->getUsername($request);
$data['type'] = $this->getUserType($request);
//dd($data);
return view('admin.home', $data);
}
ContentController - getUsername & getUserType functions
public function getUsername(Request $request){
return $request->session()->has('username') ? $request->session()->pull('username') : 'username not set';
}
public function getUserType(Request $request){
return $request->session()->has('type') ? $request->session()->pull('type') : 'user type not set';
}
I used the dump and die function to see the $data[] array before loading the view
Right after successful login:
array:2 [▼
"username" => "testAdmin"
"type" => "admin"
] //works correctly, session variables seem to be set
So when I type in localhost:8000/ I expect to be redirected to /admin/home (or /user/home depending on login) but I just get sent to localhost:8000/ as if I am not logged in. So now when I manually type in /admin/home I get the following dump and die output:
array:2 [▼
"username" => "username not set"
"type" => "user type not set"
]
If you are using $request->session()->pull('username') it fetches the data i.e. username from session and deletes it at the same time.
Instead, you can use laravel's helper method session() to get data without deleting it. So now you can use session('username') to get the username.
For more info refer : https://laravel.com/docs/5.5/session
Some Suggestions:
You could have used laravel's internal Auth library to build the login system which already has lot many features you don't need to code again. https://laravel.com/docs/5.5/authentication
You can also have multi-user authentication (admin & regular user). Refer this link if you want to implement so: https://scotch.io/tutorials/user-authorization-in-laravel-54-with-spatie-laravel-permission

Laravel: Security For ADMIN and USER

I have a two different login forms for user and admin. What I want is the user should only login in their own form otherwise it should be an error, and just the same for the admin form.
I only have 1 table for both user and admin in my database. They only differ in user_type which is obviously "admin" and "user"
What I am doing is when the user tried to login in admin login form it shows an info that says 'sorry, you are not an admin in this site'. But that means that the user is still logged in.
What I want is when the tries to login in admin form I don't want it to access the system at all.
Here my code so far:
public function validateLoginResort(Request $requests){
$username = $requests->username;
$password = $requests->password;
$attempt = Auth::attempt([
'email' => $requests->username,
'password' => $requests->password,
]);
if(Auth::check()){
if(Auth::user()->type_user == 'admin'){
return redirect('home');
}
else{
Auth::logout();
return redirect('login');
}
}else{
return "Invalid input";
}
}
I tried using Auth::logout if the user is not an admin but I dont think it is safe and right at all.
I think there is still a better way to do this, can you guys give a suggestion on how to implement this correctly? Thank you
You could check user type first, and then login user if he/she is admin.
Suppose your user table name is "users" and corresponding eloquent model is "User", then you could do this:
$user = User::where('email', $request->get('email'))->first();
if (!$user || !\Hash::check($request['password'], $user->password)) {
return 'Invalid user credential';
}
if ($user->type_user !== 'admin') {
return 'Only admin allowed';
}
\Auth::login($user); // This is the key point.
return redirect('home');
You're struggling in creating custom code in laravel how the thing works. I suggest you use the laravel package located here: https://github.com/spatie/laravel-permission it allows you to manage user permissions and roles in a database
Thanks,

Laravel Socialite log out and database storing

I am trying to set up Socialite in Laravel for facebook logging. I got user logged in , but now I have a problem storing the details in the database.
Also I would like to know how to notice my app that User is logged in? For normal loggin I used native AuthController and everything goes smooth.
Now if user try to log in again, then Laravel automatically redirect it to the url without logging, with appended code like this ?code=AQBCM-KbFqB-VJepSJ-45nFURnsvPPdpdqOu...
So how can I logout the user completely and how can I store the details for the next logging??
This is what I am using but it is not working:
public function getSocialAuth($provider=null)
{
if(!config("services.$provider")) abort('404'); //just to handle providers that doesn't exist
return $this->socialite->with($provider)->redirect();
}
public function getSocialAuthCallback($provider=null)
{
if($user = $this->socialite->with($provider)->user()){
dd($user);
/* This is also not working:
$user1 = new User;
$user1->facebook_id = $user->getId();
$user1->email=$user->email();
$user1->fullname=$user->name();
$user1->provider="facebook";
$user1->save();*/
// not working:
User::create([
'facebook_id' => $user->getId(), 'email' => $user->email(),
'fullname' => $user->name()
]);
}else{
return 'something went wrong';
}
}

Cakephp 3.x way to check if a user exists in the database

I want to create a simple check if a user exists in my database just after he is logged on (LDAP Authentication). If he doesn't exist, a record should be created in the db.
Is there any standard CakePHP 3.x -way of doing such things?
Or I can just create a function in my "users" Controller which checks if a user exists in the db and call it in the end of login() function (if user session has been successfully created)?
public function login(){
if ($this->request->is('post')){
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
$this->createStudent($user);
return $this->redirect($this->Auth->redirectUrl());
}
// user is not identified
$this->Flash->error('Your username or password is not correct');
}
}
public function createStudent($user){
$studExists = $this->Students->find('isExists', ['uid' => $user['uid']]);
if (!$studExists) {
$student = $this->Students->newEntity();
$data = ['id' => $user['uid']];
$student = $this->Students->patchEntity($student, $data);
if ($this->Students->save($student)) {
$this->Flash->success(__('It is your first logon. You have been added to our database!'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('You could not be saved in our database. Please, try again.'));
}
}
}
Thank you in advance.
What you have shown works but a better way would using an event from your LDAP authenticate class to notify that a new user record needs to be created in your app. Your table's createStudent() can be set as a listener callback for that event. Also your LDAP authenticate class should also only return info if a matching record is found in your datbase table, which I don't think is the case currently.
You can refer to this HybridAuthAuthenticate which does similar. The readme of the plugin shows how to setup listener for the event.

Categories