Postman GET request not supported on a POST request - php

I have a simple route in Laravel 8 to return some request data. But when I send the request in Postman with POST selected, I get an error of "The GET method is not supported for this route." Keep in mind, I have POST selected in Postman, not GET.
Here is the route:
Route::post('post-route', 'UserController#postFunction');
Here is is the function being called in UserController:
public function postFunction(Request $request) {
return [
'id1' => $request->id1,
'id2' => $request->id2,
];
}
In Postman I am passing the data as json:
{
'id1': 1234,
'id2': 4321
}
I am simply trying to make sure I am passing the correct data in the request but I am getting this error. Why is it trying to hit a GET request?

You can't test your POST, PUT or DELETE routes with Postman because Laravel uses the CSRF middleware protection.
If you really want to use Postman, you need to comment it to disable this middleware temporarly in app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
(...)
//\App\Http\Middleware\VerifyCsrfToken::class,
],
(...)
];
But don't forget to enable it again once you want to deploy your project in production!
If you don't want to disable temporarly the CSRF middleware, you can follow the steps mentioned here https://gist.github.com/ethanstenis/3cc78c1d097680ac7ef0, but it's a little longer.

Related

Laravel Passport Middleware "auth:api" Always Returns 401 with Valid Token

I am creating a Laravel API and want to secure it with Laravel Passport, however, it seems I can't get authenticated.
I began by securing my API routes using the Middleware auth:api inside my RouteServiceProvider.php
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('auth:api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
I also made sure to change the API driver in my config/auth.php to use passport
'api' => [
'driver' => 'passport',
'provider' => 'users',
'hash' => false,
],
I've then generated token using the methods recommended in the Laravel Docs. I did this inside of Postman.
I then used the Bearer token in the request Headers, along with the Accept and Content-Type being set to application/json (I've seen a lot on this issue in which people said this should be done)
And the Route in my api.php
Route::prefix('auth')->name('auth.')->group(function() {
Route::get('/user', function() { return response()->json(['error' => false, 'message' => 'Hello World']); })->name('user');
});
However, when I send the request I received the same 401 error given by Laravel Foundations Handler.php (I've edited the response to fit my use case but that has no affect on my current issue)
"messsage": "Unauthenticated."
Returning with the following headers;
While doing my research I found a question which described what I was experiencing but it seemed that it has been abandoned and no answer was provided. Any ideas?

Can't get Auth object and cookies by consuming my own Laravel API

I'm currently trying to build a secure SPA application in Laravel by using :
Laravel 5.6
Laravel Passport
Guzzle client
To make the whole application secure, I created a proxy to prefix all requests to the API and :
User the password grand type of token
Hide the client ID
Hide the client secret
Add automatic scopes based on the role of the user
This is how the Proxy works :
// The proxify endpoint for all API requests
Route::group(['middleware' => ['web']], function ()
{
Route::any('proxify/{url?}', function(Request $request, $url) {
return Proxify::makeRequest($request->method(), $request->all(), $url);
})->where('url', '(.*)');
});
Each time a request is made, it goes through that package I built to create the access token, refreshing it, or deleting it.
To create the access token for the user I'm using a MiddleWare at loggin :
$response = $http->post('http://myproject.local/proxify/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'username' => $request->get('email'),
'password' => $request->get('password'),
]
]);
This is working well, excepting the fact that I'm setting cookies in the Proxify::makeRequest, so I have to create them in the call, return them in the $response, and then at the end of the Middleware, attaching them to the request (Cookie::queue and Cookie::Make are not working in a Guzzle call it seems).
The access token is created and stored in a cookie.
First problem is that in this call, even in the middleware, and especially in that URL http://myproject.local/proxify/oauth/token, I don't have any access to the Auth trait, even if it's specified as a middleware attached to the route, so impossible to fetch information from the authenticated user.
Then the other problem is that when I'm making a call to get a ressource API such as :
$http = new Client();
$response = $http->get('http://myproject.local/proxify/api/continents');
$continents = $response->getBody()->getContents();
return view('dashboard')->with("continents", $continents);
In that case, when I'm calling the URL, the proxy is not able to get the access_token defined in the cookie with the CookieFacade through the HTTP call, neither the Auth object I'm whiling to use. The $_COOKIE variable is not working neither.
What is wrong with my structure so that I don't have any access to the cookie even if it's set and in the browser ? Any other way to get the info ? I tried to get the cookie from the request in the proxy, not working.
Have you tried using the Illuminate or Symfony Request classes and handling the routing via the Laravel instance? My immediate suspicion is Guzzle is the culprit behind no cookies coming through with the requests. Cookie::queue() is a Laravel specific feature so I wouldn't think Guzzle would know anything about them.
Replace Guzzle in one of the routes where the issue occurs. Start with a new Request instance and make the internal api call like:
// create new Illuminate request
$request = Request::create('/api/users', $action, $data, [], [], [
'Accept' => 'application/json',
]);
// let the application instance handle the request
$response = app()->handle($request);
// return the Illuminate response with cookies
return $response->withCookies($myCookies);
I do something similar to this in a couple applications and never had any problems with cookies or accessing server variables. Granted, it's only for authentication, the rest of the api calls are through axios.

Laravel Passport: auth:api behaving like auth:web

I am trying to implement passport in my application to authenticate the api calls. I have done the configuration as mentioned in the official documentation.
I have this in my auth guard:
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
And, this in my AuthServiceProvider's boot() method:
Passport::routes();
And this is the route I am trying to access:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::group(['namespace' => 'Api', 'middleware' => 'auth:api'], function () {
// Login Controller
Route::get('/getclc', 'PreController#getClc');
});
I am sending the header in the request like this:
Authorization:Bearer $accessToken
My question is: 1. When a protected route is requested, it sends me to login page, but I want it to return the 401. How can I do that?
My laravel version is 5.4.33.
When authentication fails, Laravel throws an AuthenticationException exception. This exception is handled by your Laravel exception handler, and eventually calls the unauthenticated() method in your app/Exceptions/Handler.php file.
You can see from that method that if your request expects a json response, you'll get a 401 Unauthenticated response. However, if you're not expecting a json response, it just redirects to the route named "login". This will obviously fail if you don't have a route named "login".
Your request "expectsJson" when you send either the "X-Requested-With: XMLHttpRequest" header, or the "Accept: application/json" header. Otherwise, it is considered a normal web request.
If you'd like to change how your application handles unauthenticated users, the unauthenticated() method is the one to change.
Add this code on Headers on postman.
key Value
Accept application/json
Thanks

Laravel 5.3 API

When user enter username and password on the the browser and successfully logged in.
I like to make some API requests after user have logged in.
Laravel 5.3 provide api.php in routes folder.
in api.php I have included:
Route::group(['middleware' => ['auth']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
When requesting domain.com/api/test on the browser, for some reason it is redirecting to /home?
API token is not needed.
If you are specifying routes in api.php, you will need to use the auth:api middleware. So using your example it would be:
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
Notes about Token auth and Laravel 5.3:
If you've setup laravel's default auth system, you will also need to add a column for api_token to the user table. If you are using DB seeders, you might want to add something like:
$table->char('api_token', 60)->nullable();
to your users table seeder. Alternatively just add the column manually and fill that column with a random 60-char key.
When making the request, you can add the api_token as a URL/Querystring parameter like so:
domain.com/api/test?api_token=[your 60 char key].
You can also send the key as a header (if using Postman or similar), i.e:
Header: Authorization, Value: Bearer [your 60 char key].
I order to get a useful error if the token is incorrect, and not just be redirected to login, also send the following header with all requests:
Header: Accept, Value: application/json. This allows the expectsJson() check in the unauthenticated() function inside App/Exceptions/Handler.php to work correctly.
I found it hard to find clear docs from Laravel about using token auth with 5.3, I think it's because there's a drive to make use of Passport, and it supports tokens in a different way. Here's the article that probably helped most getting it working: https://gistlog.co/JacobBennett/090369fbab0b31130b51
first install the passport as stated here laravel passport installation
while consuming your own api add below line in your config/app.php in middleware section
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
now change your route to
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
now in your config/auth.php change these lines
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
The reason you are being redirected back to home is because the auth middleware checks if a user session is stored in your browser, but since api middleware does not make use of sessions (see app\http\kernel.php), your request is considered unauthenticated
If you would like to perform simple APIs that utilize sessions, feel free to add them in your web routes, and make sure to secure them by grouping them inside an auth middleware.
The standard behaviour in Laravel 5.5 is to delegate handling of authentication exceptions to app/Handler::unauthenticated(), in your project's application code. You'll find the code in there that redirects to the login page, and you can override it or perform further tests and contextualization in there. In previous versions of Laravel, 5.3 among them I believe, this exception handling was executed way down within the Laravel library within the vendor folder.

Laravel 5.2 PHPUnit JSON Api request body not being set

I am testing POSTing data to an API endpoint we've created using Laravel 5.2, but none of the parameters seem to be reaching the application in the test. The endpoint expects json and responds with json and uses a FormRequestValidator which has required rules for active and make parameters. The test fails with status code 422 and the examining the response body it states the active and make parameters are required even though they are being passed in the call so therefore for some reason when the request reaches the the Form Request Validator, the input is not there.
However, when I invoke the endpoint with json body including make and active from Postman or the UI app we've built it works fine, it is only failing in the PHPUnit tests therefore it must be something with PHPUnit or the test setup being incorrect. Here is the test:
public function testItStoresCars()
{
// Arrange
$user = User::first();
//Act
$this->json(Request::METHOD_POST, '/v1/cars', [
'active' => true,
'make' => 'Audi'
],
['Authorization' => 'Bearer '.\JWT::fromUser($user)]));
// Assert
$this->assertResponseOk();
}
I know the Authorisation header is set correctly from other tests passing.
I've tried disabling middleware, using the $this->post helper method and manually setting the headers as well as using the $this->call method with setting the Headers and encoding the data using json_encode but I always get the same 422 response. I'm wondering has anyone encountered this issue or can see an error?
Controller Code
public function store(CreateCarRequest $request)
{
$car = $this->carRepo->save($request->all());
return response()->json(car);
}
FormRequest
class CreateCarRequest extends Request
{
public function rules()
{
return [
'active' => 'required|boolean',
'make' => 'required',
];
}
}
422 is the error response for validation errors.. which means either your data is not posted or it doesn't pass server validation, try
$this->json(Request::METHOD_POST, '/v1/cars', [
'active' => true,
'make' => 'Audi'
],
['Authorization' => 'Bearer '.\JWT::fromUser($user)]))->dump();
dump() should show you the errors

Categories