I am having issues passing user details after authenticating the user. The variable $newUser has the required information, but it can't be passed to the user.index view. I am using Laravel 5.1.
Route::get('user/home', ['as' => 'home', function () {
return view('user.index');
}]);
Route::get('{provider}/login', function ($provider) {
global $newUser;
OAuth::login($provider, function ($user, $userdetails) {
$newUser = $userdetails;
$email = DB::table('users')->where('email', $newUser->email)->value('email');
if( isset($email)) {
echo "Welcome " . $newUser->full_name . " <br/>";
}
else {
echo "New User! <br/>";
$user->name = $newUser->full_name;
$user->email = $newUser->email;
$user->save();
}
});
$newUser = (array) $newUser;
return view('user.index', $newUser);
});
Try:
view('user.index', compact('newUser'));
Well just wondering, why don't you use a controller and make your code more explicit so that coming back to your coding 6 months from now would be easy for you to understand.
Anyway, if your using the Auth facade, you should be able to use
Auth::user()
inside your view to retrieve it or try seeing the available method of the OAuth class. Or if you want to keep your code as it is try
return view('user.index', compact('newUser'));
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.
My laravel application is a social media site. Here's the route for visiting another laravel user's profile
Route::get('/dashboard/{id}', [
'uses' => 'UserController#getProfile',
'as' => 'profile.index',
'middleware' => 'auth'
]);
It works just fine. However, I've discovered a bug that when I input the Auth user's ID into the route, I get taken to the same page where I can then add myself as a friend, I do not want this to happen. I would rather get taken back to the home screen if I'm visiting my own profile.
Here's the controller:
public function getProfile($id)
{
if(Auth::user() === $id)
redirect('dashboard');
$user = User::where('id', $id)->first();
$posts = Post::where("dash_id", "=", $user->id)->latest()->paginate(3);
$photos = Photo::paginate(6);
return view('profile.index',compact('user','posts', 'photos'));
}
I've tried to get it to redirect to 'dashboard' instead of 'profile.index' if it's the Auth user's page instead of pulling up just like a regular non-auth profile, but can't seem to get it to work. Any ideas on how to fix this small bug?
You get user instance by Auth::user() not only the user ID. You are comparing instance with the numeric value. It will not work. You have to use Auth::id() or Auth::user()->id in order to get ID of the logged in user. The following code will work in your case.
public function getProfile($id)
{
if(Auth::id() == $id)
{
redirect('dashboard');
}
else
{
$user = User::where('id', $id)->first();
$posts = Post::where("dash_id", "=", $user->id)->latest()->paginate(3);
$photos = Photo::paginate(6);
return view('profile.index',compact('user','posts', 'photos'));
}
}
Let me know if it helps!
You try to compare the current user object to the request id, try this code:
public function getProfile($id)
{
if(Auth::id() === $id) {
redirect('dashboard');
}
$user = User::where('id', $id)->first();
$posts = Post::where("dash_id", "=", $user->id)->latest()->paginate(3);
$photos = Photo::paginate(6)
return view('profile.index',compact('user','posts', 'photos'));
}
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.
I'm building a laravel application where A user logged in other device and While logged out I want to force him to logged out from other device also. How do I implement in laravel.
Personally I have used Redis Server. While running the program I have run redis-server.exe also.And I'm in Windows.
I have changed the .env file also with CACHE_DRIVER=redis SESSION_DRIVER=redis
Besides Redis already installed with laravel I have also installed "predis/predis": "~1.0"
And Here is my Controller where I have written the login for forcing the user from logged out from other device.
In Signin controller when I dd() the $redis I see the session created for that user but when I logged in and when going to logout I dd() the $userSessions But see empty so it means nothing stored in sessions table to compare.
If anyone find any solution please help me to find it out. Thanks In Advance.
Controller:
public function postSignIn(Request $request)
{
if (Auth::attempt(['email' => $request['email'], 'password' =>$request['password'] ]) ) {
$redis = \Redis::connection();
$userId = Auth::user()->id;
$redis->sadd('users:sessions:' . $userId,Session::getId());
return redirect()->route('main');
}
return redirect()->back();
}
public function getLogout()
{
$redis = Redis::connection();
$userId =Auth::user()->id;
$userSessions = $redis->smembers('user:sessions:' . $userId);
$redis->sadd('users:sessions:'.$userId,Session::getId());
$currentSession = Session::getId();
foreach ($userSessions as $sessionId) {
if ($currentSession == $sessionId) {
continue;
}
$redis->srem('user:sessions:' . $userId, $sessionId);
$redis->del('laravel:' . $sessionId);
\Session::setId( $sessionId );
\Session::clear();
}
Auth::logout();
return redirect()->route('main');
}
Using Redis with Laravel You can use sth like this:
// During LogIn
Cache::tags(['sessions', auth()->id])->forever('session:'.auth()->id, Session::getId());
// Logout
Cache::tags([auth()->id])->flush();
Tags allows to You remove all keys stored with concrete tag.
[Updated]
You have to fit session variable names.
public function postSignIn(Request $request)
{
if (Auth::attempt(['email' => $request['email'], 'password' =>$request['password'] ]) ) {
$userId = Auth::user()->id;
\Cache::tags(['sessions', 'session_'.$userId])->forever('users:sessions:' . $userId, Session::getId());
return redirect()->route('main');
}
return redirect()->back();
}
public function getLogout()
{
$userId =Auth::user()->id;
$sessionId = \Cache::get('users:sessions:' . $userId);
\Cache::tags(['session_'.$userId])->flush();
\Session::setId( $sessionId );
\Session::clear();
Auth::logout();
return redirect()->route('main');
}
I want to use Laravel 5 AuthServiceProvider to prevent logged in user to view other users profile. I'm using route like this user/1. How can I compare if the logged in user ID is match with the ID in the URL. If not then can't proceed.
Here's the following code I'm trying in my AuthServiceProvider:
$gate->define('view-profile', function($user, $id) {
return Auth::user()->id === $id;
});
However, the above code doesn't work as I can't pass the correct ID from the URL. Can anyone please help?
Here's the code I've in my controller:
if (Gate::denies('view-post', [Auth::user()->id, (int) $id])) {
return abort(403);
} else {
return 'success';
}
Just to let all of you know that I've figured it out myself using Gate::forUser() method. Here's the relevant code which I hope anyone may find helpful:
In AuthServiceProvider:
$gate->define('view-post', function($user, $id) {
return $user->id === (int) $id;
});
In your particular Controller:
$user = Auth::user();
if(Gate::forUser($user)->allows('view-post', $id)) {
return 'true';
}
return abort(403, trans('Sorry, not sorry!'));
If you route user controller with user, then user/1 will route the user controller show function, and in show function you can check your authentication user with id:
Function show ($id)
{
if ( Auth::user()->id == $id) {
//your code here
}
}