The class 'App\Entity\User' was not found in the chain configured namespaces - authentication

I am running into the error:
The class 'App\Entity\User' was not found in the chain configured namespaces
I am running Symfony 4.2 with API Platform. I need to create an API token/key authentication setup and am using the guard authenticator.
Entity:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #ORM\Table(name="arc_sync_api_keys")
*/
class User implements UserInterface
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue
*/
public $id;
/** #ORM\Column(length=20) */
public $username;
/** #ORM\Column(name="api_token", length=40) */
public $apiKey;
/** #ORM\Column(length=30) */
public $roles = [];
public function getUsername(): string
{
return $this->username;
}
public function getRoles(): array
{
return array('ROLE_USER');
}
public function getPassword()
{
}
public function getSalt()
{
}
public function eraseCredentials()
{
}
}
Authenticator:
namespace App\Security;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
class ApiKeyAuthenticator extends AbstractGuardAuthenticator
{
...
public function getUser($credentials, UserProviderInterface $userProvider)
{
$apiKey = $credentials['token'];
if (null === $apiKey) {
return;
}
// if a User object, checkCredentials() is called
return $userProvider->loadUserByUsername($apiKey);
}
...
}
security.yaml
security:
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
entity:
class: App\Entity\User
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
logout: ~
guard:
authenticators:
- App\Security\ApiKeyAuthenticator
The error happens here:
return $userProvider->loadUserByUsername($apiKey);
after following it through it fails to load the driver, but I do not know how to fix this issue. Thanks!

I had the same problem when working with multi EntityManager.
An exception like
AuthenticationServiceException 'App\\Entity\\User' was not found in the chain ..
This exception was only in production env.
I solved it by adding a default_entity_manager :
# config/packages/prod/doctrine.yaml
doctrine:
orm:
default_entity_manager: 'your default entity manager name'
# ...

Related

in laravel hasMany() relation is working but belongsTO not working

i have two tables 1: users 2: roles
as for migration of users table like this
`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->foreignId('role_id')->constrained()->onDelete('cascade');
$table->string('name');
$table->string('username');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->string('profile_image')->default('user.png');
$table->text('about')->nullable();;
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
`
as for roles table migration
`
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('role_title');
$table->string('role_slug');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('roles');
}
};
`
User mode
`
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Models\Role;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
public function role(){
return $this->belongsTo(Role::class);
}
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* #var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* #var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
`
Role model
`
<?php
namespace App\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Role extends Model
{
use HasFactory;
public function users(){
return $this->hasMany(User::class);
}
}
`
so i have tried
App\Models\Role::find(1)->users;
so it is returning
`
Illuminate\Database\Eloquent\Collection {#4831
all: [
App\Models\User {#4829
id: 2,
role_id: 1,
name: "zahid",
username: "admin",
email: "admin#gmail.com",
email_verified_at: null,
#password: "$2y$10$6Up.B4.0gytPsVWOT/f0eeG4yk.u466FDRNf34yYZwxbwyKJh8o8u",
updated_at: null,
},
],
}
`
and
App\Models\User::find(2)->roles;
it is returning null
please tell me where is my fault in code why my belogsTo not working. i want for one use lke jone or nike contains only one role lke author or admin or writer etc. but one role lke admin or it could be contain multiple users lke multiple user can be admin or author.
is in my logic any fault or in code above.
plz help me. and thank for advaced for all helpfull code loves.

Laravel Sanctum tokens() undefined

i'm new to laravel and trying to build an api for a login using sanctum.
I followed documentation, and a few tutorials but i've encountered an error where the token function is not accessible by my user class even when using HasApiToken.
here is my user model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
'alt_id',
'country_id',
'birth'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'type',
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function country()
{
return $this->hasOne(Country::class);
}
}
[this is the error message][1]
[1]: https://i.stack.imgur.com/QzGK9.png
I also already checked the route in config/auth.php and it is App\Models\User::class
I've solved that problem by adding $user->tokens()->delete(); into my AuthController#logout,
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class AuthController extends Controller
{
public function logout(User $user){
$user->tokens()->delete();
return [
'message' => 'Logged out'
];
}
}
And User model looks like this.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
protected $fillable = [
//some code
];
protected $hidden = [
//some code
];
protected $casts = [
//some code
];
}

Symfony4 resource controller

I am developing an API under symfony4 and I wish I could create a parent controller that I could use to call functions that would be repeated in another controller. Here are my controllers that I would like to extend from a parent controller:
My DeliveryController:
<?php
namespace App\Controller;
use App\Entity\DeliveryMan;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class AuthController
* #package App\Controller
* #Route("/api")
*/
class DeliveryController extends AbstractController
{
/**
* #Route(
* name="api_delivery_man_post",
* path="/delivery_man",
* methods={"POST"},
* defaults={
* "_api_resource_class"=DeliveryMan::class,
* "_api_collection_operation_name"="post"
* }
* )
*/
public function postAction(DeliveryMan $data, UserPasswordEncoderInterface $encoder): DeliveryMan
{
return $this->encodePassword($data, $encoder);
}
protected function encodePassword(DeliveryMan $data, UserPasswordEncoderInterface $encoder): DeliveryMan
{
$encoded = $encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
My AuthController:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use App\Entity\User;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
/**
* Class AuthController
* #package App\Controller
* #Route("/api")
*/
class AuthController extends AbstractController
{
/**
* #Route(
* name="api_users_post",
* path="/users",
* methods={"POST"},
* defaults={
* "_api_resource_class"=User::class,
* "_api_collection_operation_name"="post"
* }
* )
*/
public function postAction(User $data, UserPasswordEncoderInterface $encoder): User
{
return $this->encodePassword($data, $encoder);
}
protected function encodePassword(User $data, UserPasswordEncoderInterface $encoder): User
{
$encoded = $encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
As can be seen I call 2 identical actions in 2 different controllers the only difference that there would be the entities and the path of the road.
So I was thinking of creating a ResourceController parent controller that would be extended from AbstractController and that the child controllers would be extended from ResourceController but I do not see how after how to create my methods in my parent controller and retrieve them in the child controllers.
If someone has already done that I am a taker :) Thank you for your help.
EDIT Result ResourceController:
<?php
namespace App\Controller;
use App\Entity\DeliveryMan;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class ResourcesController extends AbstractController
{
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function encodePassword(User $data): User
{
$encoded = $this->encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
public function encodePasswordDelivery(DeliveryMan $data): DeliveryMan
{
$encoded = $this->encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
Just make a ResourceController wich extends Symfony AbstractController.
Write your 2 shared methods here, then in any Controller that extends ResourceController you can call them as you would normally call a class method: using $this
class ResourceController extends AbstractController
{
private $encoder;
public function __construct(UserPasswordEncoderInterface $encoder)
{
$this->encoder = $encoder;
}
public function encodePassword(Object $data): Object
{
$encoded = $this->encoder->encodePassword($data, $data->getPassword());
$data->setPassword($encoded);
return $data;
}
}
class AuthController extends ResourceController
{
public function someAction(User $data)
{
return $this->encodePassword($data);
}
}
I also suggest you write an interface with a getPassword method that User and DeliveryMan will implements. Not only you'll ensure that the method is implemented but you' also be able to typehint, say AuthenticatedEntityInterface, instead of Object

Laravel 5.2 Eloquent Relationships with Irregular Names

I'm building out my first project in Laravel and have run into a bit of a snag with a one to many relationship between two tables.
Historically, I would have done something like this in SQL to achieve my end goal:
SELECT tag_key.key
FROM tag
LEFT JOIN tag_key
ON tag.tag_key_id = tag_key.id;
With Laravel, I'm trying to do things the ORM way and am getting hung up, probably on a naming thing somewhere down the pipe. Here's the code:
Part 1: Migrations:
"tag_keys" table
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagKeysTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tag_keys', function (Blueprint $table) {
$table->increments('id');
$table->string('key', 128);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('tag_keys');
}
}
"tags" table
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTagsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->increments('id');
$table->string('value', 128);
$table->integer('tag_key_id')->unsigned()->index();
$table->foreign('tag_key_id')->references('id')->on('tag_keys')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('tags');
}
}
Part 2: Models:
"TagKey" model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class TagKey extends Model
{
protected $fillable = [
'key'
];
protected $dates = [];
protected $table = 'tag_keys';
/**
* Tag Keys have many Tags
*/
public function values()
{
return $this->hasMany('App\Tag');
}
}
"Tag" model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tag extends Model
{
protected $fillable = [
'value',
'tag_key_id'
];
protected $dates = [];
/**
* Tag values belong to Tag Keys
*/
public function key()
{
return $this->belongsTo('App\TagKey');
}
}
Independently, they both work just fine. However, when I jump into tinker and try this (given there is a valid row in both the "tag" and "tag_key" tables and given that id 1 in the "tag" has the value of 1 in the "tag_key" table under the "tag_key_id" column):
$tag = App\Tag::first();
$tag->key;
=> null
What am I missing here? How do I build this association?
When the foreign key name doesn't follow Eloquent conventions ("snake case" name of the owning model and suffix it with _id), you should specify it in the relationship:
TagKey object:
return $this->hasMany('App\Tag', 'tag_key_id');
Key object:
return $this->belongsTo('App\TagKey', 'tag_key_id');
More info in the documentation

Please explain the foreign_key and local_key in Laravel ORM relationships

I'm effectively trying to define the relationships between users (sender and recipient) and messages.
My Messages migration is:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMessagesTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
//
Schema::create('messages', function($t){
$t->increments('id');
$t->integer('sender_user_id')->unsigned();
$t->integer('recipient_user_id')->unsigned();
$t->string('subject');
$t->text('content');
$t->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
//
Schema::dropIfExists('messages');
}
}
My Message model was straightforward:
<?php
class Message extends Eloquent{
// link to sender user id
public function from(){
return $this->hasOne('User', 'sender_user_id');
}
// link to recipient user id
public function to(){
return $this->hasOne('User', 'recipient_user_id');
}
}
But I'm unsure in defining the hasMany relationships in my User model.
The docs (http://laravel.com/docs/eloquent#relationships) shows the following:
return $this->hasMany('Comment', 'foreign_key');
return $this->hasMany('Comment', 'foreign_key', 'local_key');
Now, I'm confused which key is which in the latter hasMany relationship. Which is correct for my User model?
public function sentMessages(){
return $this->hasMany('Messages', 'id', 'sender_user_id');
}
public function sentMessages(){
return $this->hasMany('Messages', 'sender_user_id', 'id');
}
You have to set your relation like this:
public function sentMessages()
{
return $this->hasMany('Messages', 'sender_user_id');
}
public function receivedMessages()
{
return $this->hasMany('Messages', 'recipient_user_id');
}