I am trying to implement JWT authentication with laravel 5.7 but i am facing an issue while sending a request in Laravel. the error is as follows.
error: Object { message: "Class App\\Http\\Controllers\\App\\Http\\Controllers\\AuthController does not exist", exception: "ReflectionException", file: "C:\\Users\\DELL\\Desktop\\laravel+angular\\backend\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php", … }
headers: Object { normalizedNames: Map(0), lazyUpdate: null, lazyInit: lazyInit()
}
message: "Http failure response for http://localhost:8000/api/login: 500 Internal Server Error"
name: "HttpErrorResponse"
ok: false
status: 500
statusText: "Internal Server Error"
url: "http://localhost:8000/api/login"
here is my auth controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;
class AuthController extends Controller
{
/**
* Create a new AuthController instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
/**
* Get a JWT token via given credentials.
*
* #param \Illuminate\Http\Request $request
*
* #return \Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return response()->json(['error' => 'Unauthorized'], 401);
}
/**
* Get the authenticated User
*
* #return \Illuminate\Http\JsonResponse
*/
public function me()
{
return response()->json($this->guard()->user());
}
/**
* Log the user out (Invalidate the token)
*
* #return \Illuminate\Http\JsonResponse
*/
public function logout()
{
$this->guard()->logout();
return response()->json(['message' => 'Successfully logged out']);
}
/**
* Refresh a token.
*
* #return \Illuminate\Http\JsonResponse
*/
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
/**
* Get the token array structure.
*
* #param string $token
*
* #return \Illuminate\Http\JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => $this->guard()->factory()->getTTL() * 60,
'user'=> auth()->user()->name
]);
}
/**
* Get the guard to be used during authentication.
*
* #return \Illuminate\Contracts\Auth\Guard
*/
public function guard()
{
return Auth::guard();
}
}
it says AuthController does not exist where as i checked and i have it in my http->controller folder in laravel project. please help me ! Thanks ..!!
This looks like a namespace issue:
App\Http\Controllers\App\Http\Controllers\AuthController
Notice how App\Http\Controllers is repeated?
It looks like you might have forgotten a leading \, perhaps using App\Http\Controllers\AuthController instead of \App\Http\Controllers\AuthController somewhere. Without it, the namespace is relative to the current namespace of whatever script it was used in. It's similar to relative or absolute paths in files and urls.
If it happened while defining an authentication route, by default Laravel will prepend the App\Http\Controllers namespace to whatever controller name you gave as the action (you can see this defined in RouteServiceProvider.php).
Edit:
The problem seems to be caused by outdated instructions in the guide that you followed:
First let's add some routes in routes/api.php as follows:
Route::group([
'middleware' => 'api',
'namespace' => 'App\Http\Controllers',
'prefix' => 'auth'
], function ($router) {
Route::post('login', 'AuthController#login');
Route::post('logout', 'AuthController#logout');
Route::post('refresh', 'AuthController#refresh');
Route::post('me', 'AuthController#me');
});
Routes defined in routes/api.php already have a namespace of App\Http\Controllers, so the namespace given to this Route::group() is being appended to that namespace, causing the duplication I mentioned above. If you delete the 'namespace' => 'App\Http\Controllers', line you should solve this specific error.
You can see in their develop branch that the line has already been removed from the guide:
First let's add some routes in routes/api.php as follows:
Route::group([
'middleware' => 'api',
'prefix' => 'auth'
], function ($router) {
Route::post('login', 'AuthController#login');
Route::post('logout', 'AuthController#logout');
Route::post('refresh', 'AuthController#refresh');
Route::post('me', 'AuthController#me');
});
Related
I am working on a mailbox between two users for my application. I made the controller, the form and the view, everything is working except when I add the entity Ad in the MessageController to return informations about the ad, for the view.
The error message is :
App\Entity\Ad object not found by the #ParamConverter annotation.
I did exactly the same thing when I managed the booking of an ad, it all worked perfectly fine, I really don't get what's wrong with the rest.
For example, my BookingController which is working :
/**
* #Route("/ads/{id}/booking", name="ad_booking")
* #IsGranted("ROLE_USER")
*
* #return Response
*/
public function booking(Ad $ad, Request $request, ObjectManager $manager)
{
$booking = new Booking;
$form = $this->createForm(BookingType::class, $booking);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
$user = $this->getUser();
$booking->setBooker($user)
->setAd($ad)
;
if(!$booking->isAvailableDate())
{
$this->addFlash(
'warning',
'Attention, les dates que vous avez choisies ne sont pas disponibles, elles ont déjà été réservées.'
);
}
else
{
$manager->persist($booking);
$manager->flush();
$this->addFlash(
'success',
"Votre réservation a bien été effectuée !"
);
return $this->redirectToRoute('booking_show', [
'id' => $booking->getId(),
'withAlert' => true
]);
}
}
return $this->render('booking/booking.html.twig', [
'ad' => $ad,
'bookingForm' => $form->createView()
]);
}
My MessageController that doesn't work :
namespace App\Controller;
use App\Entity\Ad;
use App\Entity\Message;
use App\Form\MessageType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class MessageController extends AbstractController
{
/**
* #Route("/ads/{id}/message", name="message_provider")
* #IsGranted("ROLE_USER")
*
* #return Response
*/
public function message(Ad $ad, Request $request, ObjectManager $manager)
{
$message = New Message();
$form = $this->createForm(MessageType::class, $message);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$ad = $this->getAd();
$user = $this->getUser();
$message->setSender($user)
->setAd($ad)
;
$manager->persist($message);
$manager->flush();
$this->addFlash(
'success',
"Votre message n°{$message->getId()} a bien été envoyé."
);
return $this->redirectToRoute('message_show', [
'id' => $message->getId()
]);
}
return $this->render('message/new.html.twig', [
'form' => $form->createView()
]);
}
/**
* #Route("/message/{id}", name="message_show")
*
* #return Response
*/
public function showmessage(Message $message)
{
return $this->render('message/show.html.twig', [
'message' => $message,
]);
}
}
and my Message entity
namespace App\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\MessageRepository")
*/
class Message
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="text")
*/
private $content;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="messages")
* #ORM\JoinColumn(nullable=false)
*/
private $receiver;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="sentMessages")
* #ORM\JoinColumn(nullable=false)
*/
private $sender;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Ad", inversedBy="messages")
* #ORM\JoinColumn(nullable=false)
*/
private $ad;
/**
* #ORM\Column(type="datetime")
*/
private $createdAt;
I still got the App\Entity\Ad object not found by the #ParamConverter annotation. error message, even when I tried to define the #ParamConverter in the annotation. I can't see what's wrong.
Not sure if it's related but it seems to me, you never use the object $ad created from {id} in your function message. I think you use the id of your Ad or an object Ad on the form $this->getAd() and you never use the one on the route {id}. Maybe it messed up, try to clarify what is $ad on this function (from the route {id} or from the form).
If I had to bet, I would say you don't need this line:$ad = $this->getAd(); because you don't identify you current used $ad on the form but on the route.
(It should be a comment but I can't comment yet)
I've created my own service class and I have a function inside it, handleRedirect() that's supposed to perform some minimal logical check before choosing to which route to redirect.
class LoginService
{
private $CartTable;
private $SessionCustomer;
private $Customer;
public function __construct(Container $SessionCustomer, CartTable $CartTable, Customer $Customer)
{
$this->SessionCustomer = $SessionCustomer;
$this->CartTable = $CartTable;
$this->Customer = $Customer;
$this->prepareSession();
$this->setCartOwner();
$this->handleRedirect();
}
public function prepareSession()
{
// Store user's first name
$this->SessionCustomer->offsetSet('first_name', $this->Customer->first_name);
// Store user id
$this->SessionCustomer->offsetSet('customer_id', $this->Customer->customer_id);
}
public function handleRedirect()
{
// If redirected to log in, or if previous page visited before logging in is cart page:
// Redirect to shipping_info
// Else
// Redirect to /
}
public function setCartOwner()
{
// GET USER ID FROM SESSION
$customer_id = $this->SessionCustomer->offsetGet('customer_id');
// GET CART ID FROM SESSION
$cart_id = $this->SessionCustomer->offsetGet('cart_id');
// UPDATE
$this->CartTable->updateCartCustomerId($customer_id, $cart_id);
}
}
This service is invoked in the controller after a successful login or registration. I'm not sure what's the best way to access redirect()->toRoute(); from here (or if I should do it here).
Also if you have other comments on how my code is structured please feel free to leave them.
Using plugins within your services is a bad idea as they require a controller to be set. When a service is created and you inject a plugin it has no idea of the controller instance so it will result in an error exception. If you want to redirect the user you might just edit the response object as the redirect plugin does.
Notice that I stripped the code to keep the example clear and simple.
class LoginServiceFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new LoginService($container->get('Application')->getMvcEvent());
}
}
class LoginService
{
/**
* #var \Zend\Mvc\MvcEvent
*/
private $event;
/**
* RedirectService constructor.
* #param \Zend\Mvc\MvcEvent $event
*/
public function __construct(\Zend\Mvc\MvcEvent $event)
{
$this->event = $event;
}
/**
* #return Response|\Zend\Stdlib\ResponseInterface
*/
public function handleRedirect()
{
// conditions check
if (true) {
$url = $this->event->getRouter()->assemble([], ['name' => 'home']);
} else {
$url = $this->event->getRouter()->assemble([], ['name' => 'cart/shipping-info']);
}
/** #var \Zend\Http\Response $response */
$response = $this->event->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}
}
Now from within your controller you can do the following:
return $loginService->handleRedirect();
I am currently upgrading an extbase-extension to be TYPO3 v7 compatible,
and there is a very strange extbase behavior I simply have no clue to.
Within BackendController, A derived model has to be updated,
which looks like this:
/**
* action update
*
* #param \Vendor\MyExt\Domain\Model\Thing $thing
* #return void
*/
public function updateAction(\Vendor\MyExt\Domain\Model\Thing $thing) {
if ($this->request->hasArgument('exit')) {
$this->redirect('list');
exit;
}
$this->setFalItems($thing);
$this->updateStuff($thing);
$this->updateTypeModel($thing);
//...
}
protected function updateTypeModel( \Vendor\MyExt\Domain\Model\Thing $thing ) {
//...
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
$mytypeRepository = $this->objectManager->get('Vendor\MyExt\Domain\Repository\TypeWhateverRepository');
$typeModel = $mytypeRepository->findByUid( $TypeId );
//...
in v6, vardump( $typemodel ) showed the corresponding Object,Vendor\MyExt\Domain\Model\TypeWhatever
in v7, vardump( $typemodel ) is showing the parent Object,Vendor\MyExt\Domain\Model\Thing
Why is it working in v6?
Why is the exact same code not working in v7 anymore?
[dreams of dreaded bugs at night]
I digged a little bit deeper, This problem is somehow related to Dependency Injection.:
/**
* typeWhateverRepository
*
* #var \Vendor\MyExt\Domain\Repository\TypeWhateverRepository
* #inject
*/
protected $typeWhateverRepository;
protected function updateTypeModel(\Vendor\MyExt\Domain\Model\Thing $thing) {
// $typeWhateverRepository = $this->objectManager->get('Vendor\\MyExt\\Domain\\Repository\\TypeWhateverRepository');
$typeModel = $this->typeWhateverRepository->findByUid($thing->getTypeId());
-> still the same problem,
-> Call to undefined method Vendor\MyExt\Domain\Model\Thing::setWhatever()
So, DI didn't work at all, Grmpf.
What other prerequisites are necessary to get the DI right?
(BTW, inbetween tests, i un-and reinstall the ext, clearing all caches via installtool.)
Thank you in advance.
First of all... lets do some clean up...
I would recommend to use the inject of your repository:
/**
* seminarRepository
*
* #var \Vendor\MyExt\Domain\Repository\TypeWhateverRepository
*/
protected $typeWhateverRepository;
/**
* #param \Vendor\MyExt\Domain\Repository\TypeWhateverRepository $typeWhateverRepository
*/
public function injectTypeWhateverRepository(TypeWhateverRepository $typeWhateverRepository)
{
$this->typeWhateverRepository= $typeWhateverRepository;
}
Then I would use an Relation from Thing to Type so you don't have to fetch these from your Repository:
/**
* #lazy
* #var \Vendor\MyExt\Domain\Model\TypeWhatever
*/
protected $typeWhatever = null;
/**
* #return \Vendor\MyExt\Domain\Model\TypeWhatever $typeWhatever
*/
public function getTypeWhatever()
{
return $this->typeWhatever;
}
/**
* #param \Vendor\MyExt\Domain\Model\TypeWhatever $typeWhatever
*
* #return void
*/
public function setTypeWhatever(TypeWhatever $typeWhatever)
{
$this->typeWhatever = $typeWhatever;
}
In your Thing TCA put than:
'type_whatever' => [
'exclude' => 0,
'label' => 'LLL:EXT:my_ext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_thing.type_whatever',
'config' => [
'type' => 'select',
'foreign_table' => 'tx_myext_domain_model_typewhatever',
'items' => [
['LLL:EXT:my_ext/Resources/Private/Language/locallang_db.xlf:tx_myext_domain_model_thing.choose', 0],
],
'minitems' => 1,
'maxitems' => 1,
],
],
The Solution to this is trivial, but was hard to find, since I was doing an Extension Update.
the extbase-typoscript setup was missing the subclasses definition m)
extbase setup is usually found in the filetypo3conf/ext/my_ext/Configuration/TypoScript/setup.txt:
config.tx_extbase.persistence.classes {
Vendor\MyExt\Domain\Model\Thing {
subclasses {
0 = Vendor\MyExt\Domain\Model\TypeWhatever
}
}
}
Also note that it is necessary for the class to have a proper 'extends' definition in the Model file.
I still wonder why it worked in v6 at all - but well, nevermind.
When user sign up, system send a confirmation email to user its work good but without any email confirmation system automatic login or user can login. How can i solve this, that user should confirm email before login and if user not confirmed an email user can't be login?
i am using this project:
Yii 2 Advanced Template With Rbac User Managment
my LoginForm model code
namespace common\models;
use Yii;
use yii\base\Model;
/**
* Login form
*/
class LoginForm extends Model
{
public $email;
public $password;
public $rememberMe = true;
protected $_user = false;
/**
* #inheritdoc
*/
public function rules()
{
return [
// username and password are both required
['email', 'filter', 'filter' => 'trim'],
[['email','password'], 'required'],
['email', 'email'],
// rememberMe must be a boolean value
['rememberMe', 'boolean'],
// password is validated by validatePassword()
['password', 'validatePassword','skipOnEmpty'=>false],
];
}
/**
* Validates the password.
* This method serves as the inline validation for password.
*
* #param string $attribute the attribute currently being validated
* #param array $params the additional name-value pairs given in the rule
*/
public function validatePassword($attribute, $params)
{
if (!$this->hasErrors()) {
$user = $this->getUser();
if (!$user || !$user->validatePassword($this->$attribute)) {
$this->addError('email', Yii::t('messages','Incorrect password or email.'));
$this->addError('password', Yii::t('messages','Incorrect password or email.'));
}
}
}
/**
* Logs in a user using the provided username and password.
*
* #return boolean whether the user is logged in successfully
*/
public function login()
{
if ($this->validate()) {
return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
} else {
return false;
}
}
/**
* Finds user by [[username]]
*
* #return User|null
*/
public function getUser()
{
if ($this->_user === false) {
$this->_user = User::findByEmail($this->email);
}
return $this->_user;
}
public function attributeLabels()
{
return [
'email' => Yii::t('app','Email'),
'password' => Yii::t('app','Password')
];
}
}
it happen because the email status inactive by default, to change this status you can go to
common/models/user.php
and change the rule function from
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_INACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]],
];
}
to
public function rules()
{
return [
['status', 'default', 'value' => self::STATUS_ACTIVE],
['status', 'in', 'range' => [self::STATUS_ACTIVE, self::STATUS_INACTIVE, self::STATUS_DELETED]],
];
}
good luck
find below function in common/models/User.php
public static function findByEmail($email)
{
return static::findOne(['email'=>$email,'status'=>self::STATUS_ACTIVE]);
}
and replace it with following
public static function findByEmail($email)
{
return static::findOne(['email'=>$email,'status'=>self::STATUS_ACTIVE,'email_verification_status'=>self::EMAIL_VERIFIED]);
}
Hope this will help you
Changing status on the backend (user table) to 10 worked like charm
You need to set up SMTP for email verification but for localhost you can use the following steps.
There is a file name like 2021XXXX-162725-6907-8769.eml in the
directory of ‘#frontend/runtime/mail’.
Open it and click on the link in it, and then you got a message ‘Your
an email has been confirmed!’ in your web browser.
Now, your email is verified and you can proceed to login user.
Use sataus = 10 in user table in database it works for me.
I'd like to be able to reroute or redirect all requests to my site to a specific page, if a conditional passes. I'm assuming this would have to be done somewhere in the bootstrap or with the dispatcher, but I'm not sure exactly what the best/cleanest way to go about it would be.
No .htaccess redirects since a condition needs to be tested for in PHP
Here's what I'd like:
if( $condition ) {
// Redirect ALL Pages/Requests
}
// else, continue dispatch as normal...
The idea here is that we can setup the entire website and send everything to a splash page until a specified date/time, at which point it would 'auto launch' itself essentially.
Why bother with routing? Just a simple redirect.
maybe something like this in Bootstrap.php:
public function initSplash(){
if($splashtime && $requestIsNotForComingSoonAlready){
header('Location: /coming-soon',true,302);
die();
}
}
or you could just stick the if statement at the top of your index.php, and avoid loading the framework completely
Indeed, I'd go for a plugin.
In library/My/Plugin/ConditionallyRedirect.php:
class My_Plugin_ConditionallyRedirect extends Zend_Controller_Plugin_Abstract
{
public function routeStartup(Zend_Http_Request_Abstract $request)
{
// perform your conditional check
if ($this->_someCondition()){
$front = Zend_Controller_Front::getInstance();
$response = $front->getResponse();
$response->setRedirect('/where/to/go');
}
}
protected function _someCondition()
{
// return the result of your check
return false; // for example
}
}
Then register your plugin in application/configs/application.ini with:
autoloaderNamespaces[] = "My_"
resources.frontController.plugins.conditional = "My_Plugin_ConditionallyRedirect"
Of course, other preferences/requirements for classname prefixing and for file location would entail slightly different steps for autoloading and invocation.
If you want to do it the right way, you'd have to do it in a class after the request is created so you can modify it before the response is sent. Normally not quite in the bootstrap. Id say put it somewhere with a plugin that has access to the front controller (similar to how an ACL would work)
Thanks #David Weinraub, I went with the plugin similar to yours. I had to change a couple things around though, here's my final result (with some of my application specific stuff simplified for the example here)
<?php
/**
* Lanch project within valid dates, otherwise show the splash page
*/
class App_Launcher extends Zend_Controller_Plugin_Abstract
{
// The splash page
private $_splashPage = array(
'module' => 'default',
'controller' => 'coming-soon',
'action' => 'index'
);
// These pages are still accessible
private $_whiteList = array(
'rules' => array(
'module' => 'default',
'controller' => 'sweepstakes',
'action' => 'rules'
)
);
/**
* Check the request and determine if we need to redirect it to the splash page
*
* #param Zend_Controller_Request_Http $request
* #return void
*/
public function preDispatch(Zend_Controller_Request_Http $request)
{
// Redirect to Splash Page if needed
if ( !$this->isSplashPage($request) && !$this->isWhiteListPage($request) && !$this->isSiteActive() ) {
// Create URL for Redirect
$urlHelper = new Zend_View_Helper_Url();
$url = $urlHelper->url( $this->_splashPage );
// Set Redirect
$front = Zend_Controller_Front::getInstance();
$response = $front->getResponse();
$response->setRedirect( $url );
}
}
/**
* Determine if this request is for the splash page
*
* #param Zend_Controller_Request_Http $request
* #return bool
*/
public function isSplashPage($request) {
if( $this->isPageMatch($request, $this->_splashPage) )
return true;
return false;
}
/**
* Check for certain pages that are OK to be shown while not
* in active mode
*
* #param Zend_Controller_Request_Http $request
* #return bool
*/
public function isWhiteListPage($request) {
foreach( $this->_whiteList as $page )
if( $this->isPageMatch($request, $page) )
return true;
return false;
}
/**
* Determine if page parameters match the request
*
* #param Zend_Controller_Request_Http $request
* #param array $page (with indexes module, controller, index)
* #return bool
*/
public function isPageMatch($request, $page) {
if( $request->getModuleName() == $page['module']
&& $request->getControllerName() == $page['controller']
&& $request->getActionName() == $page['action'] )
return true;
return false;
}
/**
* Check valid dates to determine if the site is active
*
* #return bool
*/
protected function isSiteActive() {
// We're always active outside of production
if( !App_Info::isProduction() )
return true;
// Test for your conditions here...
return false;
// ... or return true;
}
}
There's room for a some improvements but this will fit my needs for now. A side note, I had to change the function back to preDispatch because the $request didn't have the module, controller, and action names available in routeStartup, which were necessary to ensure we aren't redirecting requests to the splash page again (causing infinite redirect loop)
(Also just added a 'whitelist' for other pages that should still be accessible)