I'm stuck since several hours on a the consumption of a locale API (which I created) with PHP and Guzzle on a laravel project (8.7).
I've created deux differents laravel projects on the same local server. One is providing some API routes and the second one consume it.
On the first project (which providing APIs) I've created several routes to create, read, update and delete datas from my database.
To access this API routes we need to first consume an API route called "login". This one handle the creation of a token according to a given couple email/password.
This token is needed to call all the others API routes.
The /api/login API is a POST request with email and password datas.
/api/login route declaration : (I would like to specify that this route is into the api.php file into my laravel project so the corresponding url is : http://xxx.xxx.x.xxx/site/public/api/login)
Route::post('login',[AdminController::class,'index']);
Index method for /api/login :
function index(Request $request)
{
if(!($request->ip() == "xxx.xxx.x.xxx")) {
Log::alert('Ip ' . $request->ip() . ' a tenté de se connecter à l\'Api');
return response([
'message' => ['Authentification failed']
], 403);
}
$admin = Admin::where('email', $request->email)->first();
if (!$admin || !Hash::check($request->password, $admin->password)) {
return response([
'message' => ['Email-password couple is incorrect']
], 403);
}
$token = $admin->createToken('my-app-token')->plainTextToken;
$response = [
'admin' => $admin,
'token' => $token
];
return response($response, 201);
}
In my second project I'm using Guzzle to consome my APIs.
/articles route declaration : (http://xxx.xxx.x.xxx/backoffice/public/api/login)
Route::prefix('articles')->group(function () {
Route::any('/', [ArticlesController::class, 'index'])->name('articles-index');
});
Index method for /articles :
public function index() {
$client = new \GuzzleHttp\Client();
$request = $client->request('POST', 'http://xxx.xxx.x.xxx/site/public/api/login/', [
'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
'form_params' => [
'email' => 'test#gmail.com',
'password' => 'dAvG454aquysla4'
],
'debug' => true,
]);
$response = $request->getBody()->getContents();
return view('articles.index', [
]);
}
I'm getting this error :
GuzzleHttp\Exception\ClientException Client error: 'POST http://xxx.xxx.x.xxx/site/public/api/login/' resulted in a '405 Method Not Allowed' response: <!doctype html> <html class="theme-light"> <!-- Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: Th (truncated...)
I don't understand where is my mistake...
The /api/login is correctly define in POST http method and works perfectly with Insomnia.
Does anyone have an idea or will be able to help me using Guzzle? It's the first time I'm using it.
I'm used to consume API with fetch (ajax) in JS.
Thanks ;)
I've been searching a solution in Google but couldn't find anything similar tho this.
I'm basically trying to create a custom response upon the error methodNotAllowed in the framework Laravel 8.x
So I have this route:
Route::get('/test', function(Request $request){
return response([
'status' => 200,
'data' => 'Test'
]);
});
On requesting GET:/api/test I'm getting the expected response:
{
"status": 200,
"data": "Test"
}
But when requesting POST:/api/test or any other method it obviously throws an error 405 Method Not Allowed because I haven't setup any router for this.
Is there a "cleen way" to change the error response from 405 Method Not Allowed to
{
"status": 405,
"data": "Method Not Allowed"
}
By a "cleen way" I mean not creating aditional 100 routes just for catching the right method.
The Solution was adding the custom Response to App\Exceptions\Handler by doing this:
Add this to the top:
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
And add the custom response to the method register:
public function register()
{
$this->renderable(function (MethodNotAllowedHttpException $e, $request) {
return response()->json([
'status' => 405,
'message' => 'Method Not Allowed'
], 405);
});
}
Source: https://laravel.com/docs/8.x/errors
I have a route in api.php which look like this:
Route::get('auth/logout/{token}','UserController.php';
I tested this API endpoint using Postman with these configurations:
Method: GET
Params: key = token; value = $2y$10$Xji0VW1Qq9rtF04QlXDu1ePKNKHpRA2ppjDYWNFX.37C30sd3WSIu
Header: none
URL: localhost:8000/api/v1/logout?token=$2y$10$Xji0VW1Qq9rtF04QlXDu1ePKNKHpRA2ppjDYWNFX.37C30sd3WSIu
Here is my UserController#logout:
public function logout($token){
return response()->json([
'message' => 'Logout Success',
'token' => $token
], 200);
}
As you can see there, I just want to show a message and the $token parameter in Postman. But my problem is, Postman shows me a blank response. I can't access the URL with ? as the parameter separator. But I can access the URL with /, just like host/api/v1/auth/logout/{token_value}. But it is not what I desired. Anyone can help me?
You can remove the token route parameter:
Route::get('auth/logout', 'UserController.php');
And retrieve the token from the request in the controller:
public function logout(Request $request) {
return response()->json([
'message' => 'Logout Success',
'token' => $request->token
], 200);
}
I am trying to register a user on my website with the laravel/vue.js/vuex. In my store actions, I'm calling the tryRegister action to post a request. But it keeps responding with a 401 error not authorizaed, and I don't understand why. So I made my controller as basic as it can get to just get a response and even then it keeps throwing the 401 authorization error. I'm new to back-end developing and just can't understand why this happens. I do know for sure that the route is working. How can I make my controller function give a basic response to see if it is working? And why is it giving an authorization error even tho I'm not doing anything with authorization, is that just the standard error a controller gives?
Try register action
tryRegister(context, credentials) {
return new Promise((resolve, reject) => {
axios
.post("/api/auth/register", credentials)
.then(response => {
console.log(response.data);
//context.commit("registerSucces", response.data);
resolve(response.data);
})
.catch(error => {
console.log(error.response);
reject(error);
});
});
}
Authorization controller register function
public function register(Request $request)
{
// $user = User::create([
// 'email' => $request->email,
// 'password' => $request->password,
// ]);
//$token = auth('api')->login($user);
//return $this->respondWithToken($token);
return response()->json(['message' => 'controller register']);
}
your register method of the controller is not accessible because of the auth middleware. so you are getting not authorized error. make it accessible without authorization. in the constructor method of the controller change this line like below.
$this->middleware('auth:api', ['except' => ['login', 'register']]);
login and register are controller's method which will be now accessible without authorization.
Can someone please tell me how to make my "Page not found" or something messages? For example if someone writes a link in the browser which do not exist in my project, not to show the standard error page ( Woops, something went wrong, View [bla.bla] not found ) but page specified by me?
<?php
Route::get('sendemail', 'EmailController#sendEmail');
Route::get('test', 'AuthController#getTest');
Route::get('napravisiadmin', 'ClassbookController#getIndex');
Route::group(['middleware' => ['web']], function () {
Route::group(['middleware' => ['guest']
], function () {
Route::get('login', 'AuthController#getLogin');
Route::post('login', 'AuthController#postLogin');
});
Route::get('logout', 'AuthController#getLogout');
//Admin
Route::group(['middleware' => ['auth', 'auth.admin']
], function () {
Route::group([
'prefix' => 'admin',
'namespace' => 'Admin'
], function () {
Route::controller('student', 'StudentsController');
Route::controller('profile', 'ProfilesController');
Route::controller('class', 'ClassesController');
Route::controller('subjects', 'SubjectsController');
Route::controller('teacher', 'TeachersController');
Route::controller('marktype', 'MarkTypeController');
Route::controller('rules', 'RuleController');
Route::get('{slug?}', 'PageController#getView');
});
});
//Admin
//Student
Route::group([
'middleware' => ['auth', 'auth.student'],
'prefix' => 'stu',
'namespace' => 'Stu'
], function () {
Route::get('{slug?}', 'StuController#getView');
});
//Student
//Teacher
Route::group([
'middleware' => ['auth', 'auth.teacher'],
'prefix' => 'educator',
'namespace' => 'Educator'
], function () {
Route::get('edit/{id}', 'AccountController#getEdit');
Route::post('edit/{id}', 'AccountController#saveEdit');
Route::get('account', 'AccountController#getView');
Route::get('class-subject', 'AccountController#getClassSubject');
Route::get('add-mark', 'AccountController#getAddMark');
Route::post('mark', 'AccountController#postAddMark');
Route::get('added', 'AccountController#marksList');
Route::get('statistics', 'AccountController#marksInTable');
Route::get('personalemails', 'PersonalEmailController#getView');
Route::post('personalemails', 'PersonalEmailController#personalEmail');
});
//Teacher
});
Route::get('{slug?}', 'PageController#getView');
For the "Page not found" 404 error create a view in resources/views/errors/404.blade.php and it will show when you get a 404 error.
From the documentation:
Custom HTTP Error Pages
Laravel makes it easy to return custom error pages for various HTTP
status codes. For example, if you wish to customize the error page for
404 HTTP status codes, create a resources/views/errors/404.blade.php.
This file will be served on all 404 errors generated by your
application.
The views within this directory should be named to match the HTTP
status code they correspond to.
https://laravel.com/docs/5.2/errors#custom-http-error-pages
You can always go a step further by utilising the exception handler and handling exceptions the way you desire by customising the render() method
https://laravel.com/docs/5.2/errors#the-exception-handler
For example, if you wanted to handle file not found error, Exceptions\Handler.php
public function render($request, Exception $e)
{
if ($e instanceof \Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException) {
return response()->view('errors/exceptions/file-not-found', [], 500);
}
return parent::render($request, $e);
}
You can create custom error 404 page. If someone will enter wrong URL in a browser, he will see that page.
Also, you can redirect user manually to this page with:
abort(404);
Update
I guess the problem is here:
Route::get('{slug?}', 'PageController#getView');
You're using this three times, try to remove all of them.
The thing is when Laravel doesn't find any routes, it takes {slug} and passes it to the PageController, so when you enter http://example.com/sometext, you will be transferred to the PageController with slug = sometext.
If you do not want to remove it, check for slug inside a controller and if slug means something - good. If not, just abort(404); and user will be transferred to an error page.
Also, if you're on 5.2.27 of higher, remove web middleware from routes.php (it applies automatically, and manual apply can cause errors and strage behavior).