I am developing a dashboard and I am trying to handle the errors, for this I have this code on handler.php
public function render($request, Throwable $e)
{
if($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
{
if(Auth::user() && (Auth::user()->isStaff() || Auth::user()->isAdmin()))
{
return response()->view('dashboard.404error', [], 404);
}
return response()->view('404error', [], 404);
}
elseif ($e instanceof \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException) {
return response()->view('405error', [], 405);
}
// elseif($this->isHttpException($e) && $e->getStatusCode() == '405')
// {
// return response()->view('404error', [], 404);
// }
return parent::render($request, $e);
}
But to check if the user is logged and what type it is, I have to add this middleware on kernel.php:
Middleware:
\Illuminate\Session\Middleware\StartSession::class,
But I dont know why after that my pop ups stop appering when I edit a staff or create one and I dont know why.
Normally on views I return them with something like this:
return redirect()->route('admin.operadoras')
->with('alert-msg', 'Staff edited with success')
->with('alert-type', 'danger');
And what I have on blade view is this:
#if (session('alert-msg'))
#include('partials.message')
#endif
I dont know why that middleware, interfer with this messages.
Related
I have a pretty complex Laravel application who creates a one to one polymorphic relationship in a middleware if it does not exists. The fact is that I am unable to retrieve the relationship in the same request (create in middleware, then pass it and retrieve it), I have an error 500 when I try to do this. BUT, if I a make an other request I can retrieve it... When I look into my database, I have the userable_id and type defined, I have no idea where this can probably occur.
My middleware look like this:
public function handle(Request $request, Closure $next): mixed
{
if (!Storage::disk('cecurity')->exists(config('coffre_fort.ssl_certificate.name')) ||
!config('coffre_fort.reverse_proxy.username') ||
!config('coffre_fort.reverse_proxy.password') ||
!config('coffre_fort.encryption_key')) {
return response()->json([
'error' => 'Cecurity is not configured correctly.',
], 500);
} elseif (!Auth::user()) {
return response()->json([
'error' => 'You are not authenticated.',
], 401);
}
if (!Auth::user()->cecurityAccount) {
try {
$userType = Auth::user()::class;
/** #phpstan-ignore-next-line */
if ($userType == "App\Models\Admin") {
$this->cecurityRepository->createAdminUser(Auth::user());
} else {
// It enter in this function for creating relationship
$this->cecurityRepository->createFullCustomer(Auth::user());
}
} catch (Exception $e) {
return response()->json([
'error' => $e->getMessage(),
], 500);
}
} elseif (!$this->cecurityRepository->checkConnection()) {
$this->cecurityRepository->connect(
Auth::user()->cecurityAccount->cecurity_user_id,
openssl_decrypt(
Auth::user()->cecurityAccount->password,
'AES-256-CBC',
config('coffre_fort.encryption_key'),
0,
(int) Auth::user()->cecurityAccount->encryption_iv
),
Auth::user()->cecurityAccount->coffre_id
);
}
return $next($request);
}
Then it creates the relationship as this (in the createFulCustomer() function):
$user = new Cecurity;
$user->userable_id = $customer->id_customer;
$user->userable_type = Customer::class;
And then pass the middleware to go to listFiles() function in a controller:
public function listFiles(ListFilesRequest $request): mixed
{
try {
return $this->cecurityRepository->listFiles(
$request->get('nbRowByPage'),
$request->get('pageIndex'),
);
} catch (\Exception $e) {
return response()->json([
'message' => $e->getMessage()
], 500);
}
}
Just after the middleware has passed, my database is completed (Cecurity table related):
The email verification process not working.
I send email correctly. When I click on link to verify the email, I have been redirected to login page.
It seems the route does not pass auth middleware.
This is how I defined the route:
Route::middleware('auth')->group(function () {
Route::get('email/verify/{id}/{hash}', [App\Http\Controllers\Auth\VerificationController::class, 'verify'])
->name('verification.verify');
});
This is the function in the controller (it's the standard laravel function, I did not edited it):
public function verify(Request $request)
{
if (! hash_equals((string) $request->route('id'), (string) $request->user()->getKey())) {
throw new AuthorizationException;
}
if (! hash_equals((string) $request->route('hash'), sha1($request->user()->getEmailForVerification()))) {
throw new AuthorizationException;
}
if ($request->user()->hasVerifiedEmail()) {
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect($this->redirectPath());
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
if ($response = $this->verified($request)) {
return $response;
}
return $request->wantsJson()
? new JsonResponse([], 204)
: redirect($this->redirectPath())->with('verified', true);
}
The auth middleware is the default middleware come with laravel.
I am using AuthBasic for API authentication in a Laravel project,
I have this problem: when the API request authentication is invalid instead of displaying the JSON response it returns the 401 default blade view template.
Here is the code:
app\Http\Middleware\AuthBasic.php
public function handle($request, Closure $next)
{
if (Auth::onceBasic()) {
return response()->json(["message", "Authentication Required!"], 401);
} else {
return $next($request);
}
}
Found the Solution:
app\Exceptions\Handler.php
public function render($request, Exception $exception)
{
if ($request->is('api/*') || $request->wantsJson())
{
$json = [
'success' => false,
'error' => [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
],
];
return response()->json($json, 401);
}
return parent::render($request, $exception);
}
Remove the 401 or change it to 200 from this line:
return response()->json(["message", "Authentication Required!"], 401);
See the reference, the second parameter is defining the http code to send the browser. [401] in you case.
https://laravel.com/api/5.7/Illuminate/Routing/ResponseFactory.html#method_json
This will fix your problem, probably!
public function handle($request, Closure $next)
{
$result = Auth::onceBasic();
if($result === 401)
return response()->json(["message", "Authentication Required!"]);
else
return $next($request);
}
So here is a half Solution for this problem:
vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php
public function onceBasic($field = 'email', $extraConditions = [])
{
$credentials = $this->basicCredentials($this->getRequest(), $field);
if (! $this->once(array_merge($credentials, $extraConditions))) {
//return $this->failedBasicResponse();
return response()->json(["Message" => "Authentication Required!"], 401);
}
}
So Instead of returning the Failed Basic Response it will return the JSON Message, but I don't want to make changes in Laravel Core Files, because in case of update they will get lost !
So Any Idea ?
I don’t used react-router, just simply used react with blade. Like
following:
articleManage.blade.php
#extends('layout')
#section('content')
<div id="articleManage"></div>
#stop
I try to use jwt authentication, and it works.
Here is my jwt auth middleware:
authJWT.php
try {
$token = JWTAuth::parseToken();
if (! $token->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Exception $e) {
if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
return response()->json(['error'=>'Token is Invalid 1']);
}else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
return response()->json(['error'=>'Token is Expired 2']);
}else{
return response()->json(['error'=>'Something is wrong 3']);
}
}
return $next($request);
Now I am stuck with redirection on middleware, cause it won’t work when I change it like this:
try {
$token = JWTAuth::parseToken();
if (! $token->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Exception $e) {
……
return redirect('/');
}
return $next($request);
And this is the error message I got:
TypeError: Cannot read property 'map' of undefined
at ArticleManage.render (app.js:54105)
at app.js:50033
at measureLifeCyclePerf (app.js:49313)
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (app.js:50032)
at ReactCompositeComponentWrapper._renderValidatedComponent (app.js:50059)
at ReactCompositeComponentWrapper._updateRenderedComponent (app.js:49983)
at ReactCompositeComponentWrapper._performComponentUpdate (app.js:49961)
at ReactCompositeComponentWrapper.updateComponent (app.js:49882)
at ReactCompositeComponentWrapper.performUpdateIfNecessary (app.js:49798)
at Object.performUpdateIfNecessary (app.js:2916)
Any idea how to redirect when token error?
10/17: this is my program flow
articleManage.js
let url = 'load-article';
let config = {
headers: {'Authorization': 'Bearer '+localStorage.getItem('token')}
};
axios.get(url,config).then(response=>{
this.setState({'articles':response.data.articles});
}).catch(function (error) {
console.log(error);
});
web.php
Route::get('/load-article', 'API\ArticleController#read')->middleware('jwt-auth');
ArticleController#read
public function read(Request $request){
$header = $request->header('Authorization');
$articles = Article::All();
return response()->json(['articles' => $articles]);
}
now I change middleware, cause I want to try redirection, then I get error.
public function handle($request, Closure $next)
{
// try {
// $token = JWTAuth::parseToken();
// if (! $token->authenticate()) {
// return response()->json(['user_not_found'], 404);
// }
// } catch (Exception $e) {
// if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
// return response()->json(['error'=>'Token is Invalid 1']);
// }else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
// return response()->json(['error'=>'Token is Expired 2']);
// }else{
// return response()->json(['error'=>'Something is wrong 3']);
// }
// }
// return $next($request);
return redirect('/');
}
Shot in the dark here, since you didn't post the whole articleManager component. But, make sure you're passing some sort of failure status code header on all error responses. Otherwise, Axios will read response()->json(['error'=>'Token is Invalid 1']) as a success and attempt to set state. Since response.data.articles is undefined, that's why you're getting the error. So change your middleware in authJWT.php to something like:
} catch (Exception $e) {
if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException) {
return response()->json(['error'=>'Token is Invalid 1'], 500);
} else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException) {
return response()->json(['error'=>'Token is Expired 2'], 500);
} else {
return response()->json(['error'=>'Something is wrong 3'], 500);
}
}
What I've been trying is to have the middleware do different tasks, based on the user's type.
Here is a Route group.
Route::group(array('prefix' => 'api', 'middleware' => 'admin'), function () {
Route::resource('animal', 'AnimalController');
//Other resources
});
My User model has 2 types, which can be accessed by the following way.
$this->user()->user_type_id;
Following this advice, I was trying this task, and the handle function in App\Http\Middleware\Authenticate looks like this right now.
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ((Auth::user()->user_type_id == 2) {
//If the user is of type 2, this will be triggered
if ($request->ajax()) {
return response('You are type 2.', 401);
}
//Maybe there are other libes here
} else if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
}
return $next($request);
}
I thought that this would lead the user of type 2 to get response('You are type 2.', 401), when the user visits a URL prefixed by api/animal, but I saw a message Unauthorized. in the response.
Is it possible to have the authentication middleware work in such a way?
Any advice will be appreciated.
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('auth/login');
}
} else if ($this->user()->user_type_id == 2) {
//If the user is of type 2, this will be triggered
return response('You are type 2.', 401);
}
Try this.