auth()->user() return null in ServiceProvider - laravel

i try to get the user id in ServiceProvider but auth()->user() return null after successfully login where is the problem ?
It doesn't just work in test mode
public function boot()
{
dd(auth()->user()); // => return null
try {
Permission::get()->map(function ($permission) {
// dd('$permission');
Gate::define($permission->slug, function ($user) use ($permission) {
return $user->hasPermissionTo($permission);
});
});
} catch (\Exception $e) {
report($e);
}

Try using:
use Auth;
public function boot(){
Auth::user(); //or
Auth::user()->name; //or
Auth::user()->get();
}

Related

Get null when running JWTAuth::user() in Laravel

I've been using JWT for authentication in Laravel. I have a JWTMiddleware to check authorization, which works fine, like the following.
try {
JWTAuth::parseToken()->authenticate();
} catch (Exception $e) {
return response()->json(['error' => 'Token is Invalid']);
}
User model
class User extends Authenticatable implements JWTSubject
{
use HasFactory, Notifiable;
public static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->uuid = Str::uuid()->toString();
});
static::saving(function ($model) {
$original_uuid = $model->getOriginal('uuid');
if ($original_uuid !== $model->uuid) {
$model->uuid = $original_uuid;
}
});
}
public function getJWTIdentifier()
{
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
}
Now I have a route that uses this middleware and returns an authenticated user.
Route::middleware(['jwt.verify'])->group(function () {
Route::post('/user', function () {
$user = JWTAuth::user();
return response()->json($user);
});
});
After entering this route, I get null. Why does the middleware work fine, yet I can not retrieve the user?

how to put only session auth in laravel

Web.php
Route::group(['middleware'=>'auth:admin'], function(){
Route::resource('dashboard', 'DashboardController');
Route::group(['prefix'=>'users','namespace'=>'User','as'=>'u.'], function(){
Route::resource('list', 'ListController');
Route::resource('segments', 'SegmentController');
});
Route::group(['prefix'=>'sales','namespace'=>'Sales','as'=>'s.'], function(){
Route::resource('credits', 'CreditController');
Route::resource('packages', 'PackageController');
});
});
RedirectIfAuthenticated
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard)
{
if(Session::has('admin_session')){
return redirect('admin/dashboard');
}
// if (Auth::guard($guard)->check()) {
// return redirect(RouteServiceProvider::HOME);
// }
return $next($request);
}
}
AuthController
public function login(Request $request)
{
$serviceAccount = ServiceAccount::fromJsonFile(__DIR__.'/firebaseKey.json');
$firebase= (new Factory)->withServiceAccount($serviceAccount)->create();
$this->database = $firebase->getDatabase();
$auth = $firebase->getAuth();
// if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password])) {
// return redirect('admin/dashboard');
// }
try {
if($user = $auth->verifyPassword($request->email,$request->password)){
Session::put('admin_session',$user);
return redirect('admin/dashboard');
}
} catch (\Kreait\Firebase\Exception\Auth\InvalidPassword $e) {
echo 'wrong password'; die();
} catch (\Kreait\Firebase\Auth\SignIn\FailedToSignIn $e) {
echo 'invalid email'; die();
}
}
How to put only session authentication on above-mentioned routes?
As I want to put firebase authentication so laravel's wouldn't work here,
So I just want to implement simple isset(session('admin_session')) functionality which will be common for all routes...
Anyone, please suggest me how to implement it... it keeps redirecting!
Change the middleware group to a new middleware name:
Web.php
Route::group(['middleware'=>'role'], function(){ //or the name you want to use
Route::resource('dashboard', 'DashboardController');
Route::group(['prefix'=>'users','namespace'=>'User','as'=>'u.'], function(){
Route::resource('list', 'ListController');
Route::resource('segments', 'SegmentController');
});
Route::group(['prefix'=>'sales','namespace'=>'Sales','as'=>'s.'], function(){
Route::resource('credits', 'CreditController');
Route::resource('packages', 'PackageController');
});
});
Create a new middleware by php artisan make:middleware Role :
Role.php (Middleware)
<?php
namespace App\Http\Middleware;
use Session;
use Closure;
class Role
{
public function handle($request, Closure $next)
{
if(Session::has('admin_session')) {
return $next($request);
}
return redirect()->route('login');
}
}
Modify the RedirectIfAuthenticated middleware to this:
RedirectIfAuthenticated.php
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if (Session::has('admin_session')) {
return redirect('admin/dashboard');
}
return $next($request);
}
}
Modify AuthController to this:
AuthController.php
public function login(Request $request)
{
if ($auth = $this->firebase->getAuth()) {
try {
$user = $auth->verifyPassword($request->email, $request->password);
Session::put('admin_session',$user);
return redirect('admin/dashboard');
}
catch (\Kreait\Firebase\Exception\Auth\InvalidPassword $e) {
return back(); // code for wrong password
}
catch (\Kreait\Firebase\Auth\SignIn\FailedToSignIn $e) {
return back(); //code for user doesn't exists
}
}
return back(); // something went wrong
}

Call to a member function hasAnyRole() on null

I am new on laravel. I am actually having a problem with my middleware. I already registered it on Kernel.php file.
public function handle($request, Closure $next){
$user = Auth::user();
if($user->hasAnyRole('school'))
{
return $next($request);
}
return redirect('login');
}
here is my User model
public function roles(){
return $this->belongsToMany('App\Role');
}
public function hasAnyRoles(){
return null !== $this->roles()->whereIn('name', $roles)->first();
}
public function hasAnyRole(){
return null !== $this->roles()->where('name', $role)->first();
}
Try flipping the logic and also checking if logged in.
Do a (Auth::check() :
public function handle($request, Closure $next){
if (Auth::check()) {
$user = Auth::user();
if($user->hasAnyRole('school'))
{
return $next($request);
}
} else {
return redirect('login');
}
}

auth()->user() returns null in ServiceProvider when Feature testing

I have a code I wrote for Role permissions that loads up through a ServiceProvider.
It works fine generally, but for some reason in Feature Tests auth()->user() returns null;
I am "actingAs()" in the test.
Any idea why this works just fine normally but fails to give me an id in feature tests?
public function boot()
{
try {
dd(auth()->user()); // => return null
Permission::get()->map(function ($permission) {
Gate::define($permission->slug, function ($user) use ($permission) {
return $user->hasPermissionTo($permission);
});
});
} catch (\Exception $e) {
report($e);
return false;
}
}
What is the problem?

Laravel 7.0 - tymon/jwt-auth - check if token is valid

Trying to achieve a login endpoint at a laravel installation by using tymon/jwt-auth (JWT). The login, logout, get userdata is working fine. I would like to have a endpoint for checking the Bearer Token. There is a short way to achieve this via:
Route::get('/valid', function () {
return 1;
})->middleware('auth:api');
If the token is valid, the the HTTP return code == 200 but if not, a 401 code is returned. Since the endpoint is checking a token and not the authenticated communication, I would like to rather have a controller returning true/false regarding valid token with 200 - OK.
I had a look "under the hood" of the modules and that is how far I get (not working):
$tokenKey = $request->bearerToken();
$jws = \Namshi\JOSE\JWS::load($tokenKey);
$jwsSimple = new SimpleJWS($jws->getHeader());
$jwsSimple::load($tokenKey);
$jwsSimple->setPayload($jws->getPayload());
$jwsSimple->setEncodedSignature(explode('.', $tokenKey)[2]);
$tmpVal = $jwsSimple->isValid($tokenKey);
Is there any better approach to achieve this? I assume that there should be a Service Provider for that but could not figure out how to implement this. Thank you in advance.
You could remove the auth:api middleware and then have something like:
return response()->json([ 'valid' => auth()->check() ]);
Maybe this method need you:
public function getAuthenticatedUser()
{
try {
if (! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
return response()->json(compact('user'));
}
Here is the mixed output to achieve status based token validation with laravel and tymon/jwt-auth:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ValidTokenController extends Controller
{
public function __invoke(Request $request)
{
$response = (int) auth('api')->check();
$responseCode = 200;
try {
if (!app(\Tymon\JWTAuth\JWTAuth::class)->parseToken()->authenticate()) {
$response = 0;
}
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
$response = -1;
} catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
$response = -2;
} catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
$response = -3;
}
return response()->json($response, $responseCode);
}
}
// Validate Token Controller:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ValidTokenController extends Controller
{
public function __invoke(Request $request)
{
$response = auth('api')->check();
$responseCode = 200;
if(!$response) {
try {
if (!app(\Tymon\JWTAuth\JWTAuth::class)->parseToken()->authenticate()) {
$response = 0;
}
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
$response = -1;
} catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
$response = -2;
} catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
$response = -3;
}
} else {
$response = (int) $response;
}
return response()->json($response, $responseCode);
}
}

Resources