so i've come across what looks like a really peculiar issue. I had been using auth('api')->user() to get the user collection in a model method used by various controllers. For an API setup as a public route with api middleware its controller was using this model method and the code was only sporadically working.
I'll paste two versions of code below.
This version would sometimes return null for $user even if the user was logged in.
if(Auth::user()){
$user = Auth::user();
}elseif(auth('api')->user()){
$user = auth('api')->user();
}else{
$user = null;
}
The second version of code seems to always return the user collection for $user when the user is logged in.
$apiUser = auth('api')->user();
if(Auth::user()){
$user = Auth::user();
}elseif(auth('api')->user()){
$user = auth('api')->user();
}else{
$user = null;
}
I cannot for the life of me understand why the second version would work properly and the first wouldn't. I only stumbled accross that it worked whilst trying to debug the code. Can anyone try and explain!
You need to use Auth::check() to check if user logged in or not.
So you code will look like:
if (Auth::check()) {
$user = Auth::user();
}
Related
I have one problem with Laravel Socialite login, in my Chrome works normally but in rest of the people browser doesn't work (works in other browsers). Before php update in server to 7.3.18 from 7.1 and update to Laravel 6 from 5.8, all works normally. I try to clear all caches, change session mode to cookie(file before), clear session and cookies in browser but nothing solved the problem.
When try to login, give me this
And this is my code:
public function loginSocial(Request $request){
$this->validate($request, [
'social_type' => 'required|in:google,facebook'
]);
$socialType = $request->get('social_type');
return Socialite::driver($socialType)->stateless()->redirect();
}
public function loginCallback(Request $request){
$socialType = $request->session()->get('social_type');
//Aparently, this get give to $socialType null in ppl browser. I dont understand why this get doesn't works.
$userSocial = Socialite::driver($socialType)->stateless()->user();
//If use 'google' instead $socialType, works fine.
$user = User::where('email',$userSocial->email)->first();
\Auth::login($user);
return redirect()->intended($this->redirectPath());
}
I understand what you are trying to do but sometimes less is more and more is less..... the call back is being made by the provider and not the user. anyway have different methods for each social login
// Google login
public function googleSocialLogin(Request $request){
Socialite::driver('google')->stateless()->redirect();
}
// Google callback
public function googleSocialLoginCallback(){
$userSocial = Socialite::driver('google')->stateless()->user();
$user = User::where('email',$userSocial->email)->first();
\Auth::login($user);
return redirect()->intended($this->redirectPath());
}
// Facebook login
public function facebookSocialLogin(Request $request){
Socialite::driver('facebook')->stateless()->redirect();
}
// Facebook callback
public function facebookSocialLoginCallback(){
$userSocial = Socialite::driver('facebook')->stateless()->user();
$user = User::where('email',$userSocial->email)->first();
\Auth::login($user);
return redirect()->intended($this->redirectPath());
}
With your methods separated you will have different routes for different social login which IMO is far better as they are have slightly different return params and you may want to perform additional function for a particular social login in future.
I see the very same problem here: Laravel policies : code change is ignored. Is there any policy cache to clear? and here: Laravel Policy bug
I'm writing a new policy, the easiest one, over mode User to check if the logged user is the same user in the database so he can edit his profile, so...
I create the policy file:
> php artisan make:policy UserPolicy
I register the policy in AuthServiceProvider.php:
...
protected $policies = [
// 'App\Model' => 'App\Policies\ModelPolicy',
User::class => UserPolicy::class,
];
...
In UserPolicy.php I create the edit function:
public function edit(User $authUser, User $user) {
return $authUser->id === $user->id;
}
In UserController.php I have edit:
public function edit($id)
{
//
$user = User::findOrFail($id);
$this->authorize($user);
return view('user.edit', compact('user'));
}
See somwthing wrong? Me neither, because it worked... the first time. Then I wanted to change the policy, the User model has a level attribute, 1 for normal users, 5 for admins, 99 for superuser and so on. So I wanted that the admins or superuser would be able to change the user data, so I rewrote the UserPolicy.php's editfunction as:
public function edit(User $authUser, User $user) {
return ($authUser->id === $user->id) || ($user->level > 1);
}
Of course I made a mistake here, I should've checked for $authUser and nor $user. When I checked in the browsser, function returned false, and server gave me a 403
This action is unauthorized., which is okay. Now the wierd thing. I correct the fuction:
public function edit(User $authUser, User $user) {
return ($authUser->id === $user->id) || ($authUser->level > 1);
}
it returns 403...
public function edit(User $authUser, User $user) {
return true;
}
It returns 403...
I delete the function from the file... It returns 403...
I delete the register from AuthServiceProvider... Ir returns 403...
No, I'm not using Gates, or some other thing, the Laravel app is almost virgin. I have had this problem in the past, that came out of the blue, and went the same way as it came. I have no idea where to look for, what to look for... I thought that would be some interaction that I didn't grasped, so I wanted to start with the policies from the beggining of this project.
EDIT::::::::::::::::::::::::::::
This is even more absurd... If I check using can() in tinker, this /#&)"# thing does what it is supposed to do:
> php artisan tinker
>>> $user = App\User::find(1)
>>> $user->can('edit', $user)
true
>>> $user2 = App\User::find(2)
>>> $user->can('edit', $user2)
false
So, problem is here????
$this->authorize($user);
EDIT 2 ::::::::::::: SOLVED ::::::::::::::::::::::
I swear this used to work as I posted above (at least it used to work in 5). I had to change
$this->authorize($user);
for
$this->authorize('edit', $user);
Solution came from this article
I swear this used to work as I posted above (at least it used to work in 5). I had to change
$this->authorize($user);
for
$this->authorize('edit', $user);
Solution came from this article
I have an application that does authentication with JWT. It is my first time creating one. When I try to get the user object in a function, I can't find a way to do it. Here is my code:
public function getEmail(\Illuminate\Http\Request $request)
{
$user = \Auth::user();
return new JsonResponse(['message' => $user->email]);
}
It returns that the $user object is null, probably because the Auth class is related to session authentication. I am using this boilerplate: https://github.com/krisanalfa/lumen-jwt
I have looked into the code but can't find a way to get the user, can somebody help out?
Have you tried using this function?
JWTAuth::user();
According to this Guide for setting up with Lumen
You can get it from request object :
Example routes:
$app->get('/login', function (Request $request) {
$token = app('auth')->attempt($request->only('email', 'password'));
return response()->json(compact('token'));
});
$app->get('/me', function (Request $request) {
return $request->user();
});
After looking for it for hours, I found a working answer:
$user = app('Dingo\Api\Auth\Auth')->user();
I am facing a problem in the auth controller. I have almost made a project in Laravel 5.3. And the database is Clusterpoint. I have made a login function and its working fine. But now I try to implement the auth controller in laravel. It have already its own login and register controller and view. From one of the solution I update the login controller and custom middleware with postSignIn function. As per the solution it will override the auth login function. But when I try to do so it is not working. I am give below the already working code with out auth controller.
public function doLogin(Request $request)
{
$db_name='test_db';
$email=$_POST['email'];
$password=$_POST['password'];
$email_md5=md5($email);
$pass_md5=md5($password);
$cp = new Client();
$collection = $cp->database($db_name.".users");
$response = $collection->select('_id, email')->where('_id', '==' ,$email_md5)->where('password', '==', $pass_md5)->get();
$rawResponse = $response->rawResponse();
$data_array=json_decode($rawResponse, true);
$array_all=$data_array['results'];
//echo '<pre>'; print_r($array_all); die;
$count=$data_array['hits'];
if($count==1){
$value='on';
Session::set('s_val', $value);
Session::set('user_id', $email_md5);
Session::set('user_name', $email);
return redirect()->action('CampaignController#getIndex');
} else {
return redirect()->action('HomeController#showLogin');
}
}
Please guide me how to do the custom login function like above. Thanks in advance for the help.
I am using Laravel 5.1 and I am trying to test my controllers.
I have several roles for my users and policies defined for different actions. Firstly, each of the requests needs to be made by an authenticated user, so running a test with no user returns a 401 Unauthorized, as expected.
But when I want to test the functionality for authorized users, I still get the 401 Unauthorized status code.
It may be worth mentioning that I use basic stateless HTTP authentication on these controllers.
I have tried the following:
public function testViewAllUsersAsAdmin()
{
$user = UserRepositoryTest::createTestAdmin();
Auth::login($user);
$response = $this->call('GET', route('users.index'));
$this->assertEquals($response->getStatusCode(), Response::HTTP_OK);
}
and
public function testViewAllUsersAsAdmin()
{
$user = UserRepositoryTest::createTestAdmin();
$response = $this->actingAs($user)
->call('GET', route('users.index'));
$this->assertEquals($response->getStatusCode(), Response::HTTP_OK);
}
and also this (in case there was anything wrong with my new user, which there shouldn't be)
public function testViewAllUsersAsAdmin()
{
$user = User::find(1);
$response = $this->actingAs($user)
->call('GET', route('users.index'));
$this->assertEquals($response->getStatusCode(), Response::HTTP_OK);
}
but in every case I get a 401 response code so my tests fail.
I can access the routes fine using postman when logging in as a dummy user.
I am running out of ideas, so any help would be appreciated.
You need to add Session::start() in the setUp function or in the beginning of the function which user need to log in.
public function setUp()
{
parent::setUp();
Session::start();
}
or
public function testViewAllUsersAsAdmin()
{
Session::start();
$user = UserRepositoryTest::createTestAdmin();
Auth::login($user);
$response = $this->call('GET', route('users.index'));
$this->assertEquals(Response::HTTP_OK, $response->getStatusCode());
}
Through some experimentation, I found that the problem lay inside my authentication middleware. Since I want the API to be stateless, the authentication looks like this:
public function handle($request, Closure $next)
{
return Auth::onceBasic() ?: $next($request);
}
And apparently, it's not possible to authenticate a user the way I was doing it.
My solution was simply to disable the middleware, using the WithoutMiddleware trait or $this->withoutMiddleware() at the beginning of each test.