how to config sanctum laravel - php

I try to access by wrong token in sanctum laravel but it return
The GET method is not supported for this route. Supported methods: POST instead of message: unauthorized. how can I solve this ?
This is my api route:
This is my controller:
and this is my result:

First of all, you talk about token, maybe you meant JWT, which is for REST and/or JSON Web-API, and normally does not allow "get" as access-method.
Your error-message simply means that the way you try to make the request is not allowed.
Hence, either allow it by replacing:
Route::get('my-url')-> ...
With:
Route::match(['get', 'post'], 'my-url')-> ...
Or change your request to make a Post request instead of a Get request.
Example how to change?!
If you did send us an example how you make a request, we could provide you how to do it right.

Related

Method not allowed - redirect using incorrect method

I have been working on a simple Laravel Inertia Vue3 application. It has one resource route.
Route::resource('contact', \App\Http\Controllers\ContactController::class);
This provides the named routes contact.index .store .create .show .update .destroy and .edit
Nice and simple so far.
I have a useForm form variable in my Vue component with some assigned variables
let form = useForm({ ... });
I have a submit method in the same component
let submit = () => {
if(props.edit) {
form.patch(`/contact/${props.contact.id}`);
} else {
form.post(`/contact`);
}
}
Again nothing complex. The post method fires off correctly and redirects
Contact::query()->create($request->all());
return redirect()->to(route('contact.index'));
For full disclosure of the update method, please see below:
public function update(Request $request, Contact $contact): \Illuminate\Http\RedirectResponse
{
$contact->fill($request->all())->save();
return redirect()->to(route('contact.show', ['contact' => $contact]));
}
This works in the same way as store. Simple and then redirects... but it doesn't.
What happens is that it runs the patch and then calls redirect
The redirect carries the patch method through ending up with a 405 if I use the index route (declared as get). If I use back() I get the same thing. If I use the show route, it redirects in a loop because the patch route uses the same URL /contact/{contact}
I have built Laravel applications for the last 5 years and have not had an issue like this before when using a named route. Have I missed something basic? If not its possibly a configuration issue although I am not sure what.
I am running Laravel 9.19 with webpack manually installed as its been changed to Vite on the current release. I have no Vue errors or warnings and no Laravel logs.
there is a difference between PUT and PATCH requests on laravel-level.
Please run php artisan route:list - and see which one is used in your case, There is a big chance that you using PUT, not patch :)
So good ol' Laravel got me again.
Alexander Dyriavin got me on the right course with his answer about put and patch, however, it wasn't really the solution.
The solution:
form.transform((data) => ({
...data,
_method: 'PUT' //spoof added to request
})).post(`/contact/${props.contact.id}`); //sent as a post instead
The Laravel docs allow you to spoof methods https://laravel.com/docs/5.0/routing#method-spoofing by posting them with a _method field.
Simply put, a patch or put request would have always failed with a redirect from Laravel. In the past I would have used them with Axios and handled a JSON response directly.
This time I really am answering my own question.
I was a total idiot and missed a step when setting up inertia js. I was attempting to retrieve errors with the useform method and what happened was I received nothing.
So I though I would double check the docs.
Turns out I missed adding this middleware to the web middleware group in the kernel!
\App\Http\Middleware\HandleInertiaRequests::class,
I can now use the .patch method I had before and no need for any additional code

Laravel postman request returns Unauthenticated

I'm new to laravel and sorry for the silly question I've posted a request via postman with two parameters,In my routes api.php file,
Route::post('/mail', 'TripsController#mail');
with header,
Accept:application/json
And exclude the token verify in VerifyCSRKToken as,
protected $except = ['api/*',
];
and my url:
http://localhost/Movecabadmin/api/mail
It returns the message as {"message":"Unauthenticated."}
Question 1:Is I need to pass any authentication value with the request?If it is then How?
Question 2:How to get the passed parameters in my controller?
You are getting this {"message":"Unauthenticated."} because the Route::post('/mail', 'TripsController#mail');
going under some kind of authentication or middleware.
Remove that and you will get your desired result.

Error in Slim 3 because of mismatch in request uri & request method

I'm using Slim 3 Framework as my backend and a small self-written frontend (jQuery). In my frontend I have ajax commands to call my REST server.
Now I'm facing the problem that I can't use DELETE on my client because it is not matching the HTTP request method (GET).
405 Method not allowed. Must be one of: GET, PUT
The official documentation says said it is not allowed by default:
If your Slim Framework application has a route that matches the
current HTTP request URI but NOT the HTTP request method, the
application invokes its Not Allowed handler and returns a HTTP/1.1 405
Not Allowed response to the HTTP client.
Now I could use GET or PUT but that is not possibly because I already have those routes declared for other actions.
Slim Application Error:
The application could not run because of the following error:
Details
Type: FastRoute\BadRouteException
Message: Static route /api/v1/folders/ is shadowed by previously defined variable route /api/v1/folders/(.*) for method GET
// Folder routes
$this->group('/folders', function () {
$this->get('[/{params:.*}]', 'FolderController:index');
$this->post('', 'FolderController:create');
$this->put('[/{params:.*}]', 'FolderController:update');
$this->delete('/[/{params:.*}]', 'FolderController:delete');
})->add('AuthenticateMiddleware');
Could you please give me an advice on how to solve this? Isn't this a general problem in the REST-world so to speak, because I guess many frameworks act like Slim 3 and throw a 405 Method not allowed error in such particular situation where you want to use DELETE but can't because the click in the browser is GET?
As per my comment:
Is the failing request happening when you click on a link? <a></a> ? The request method has to be DELETE in order for Slim to invoke the right controller. Also note that your delete route has an extra [
Good luck !

Laravel 5.4 null csrf_token() when posting to route

I'm sending an ajax post request, and with Laravel it seems that is done by creating a post route for it. I've set it up so a csrf token is put in the header automaticaly for every ajax request using ajaxSetup. I'm attempting to then catch that header on the backend and verify the tokens match.
In my web routes (which automatically use the web middleware), this returns as expected:
Route::get('/test', function() {
return csrf_token();
});
However, when I post to a route via AJAX, like either of the below ways:
Attempt 1:
Route::post('/test', 'AjaxController#test');
In the AjaxController construct, followed by an alert in the view:
var_dump(csrf_token().',hi'); die;
Response: ',hi' (csrf_token was null).
Attempt 2:
Route::post('/test', ['test' => csrf_token().',hi', 'uses' => 'AjaxController#test']);
$test = $request->route()->getAction()['test'];
var_dump($test); die;
Response: ',hi' (csrf_token was null).
What I seem to be running into is, with get requests csrf_token() is populated, on my post request, it is not.
Any ideas?
check your route group it must apply the web middleware as
Route::group(['middleware' => 'web'], function () {
Route::get('/test', function() {
return csrf_token();
//or return $request->session()->token();
});
});
Finally figured this out.
CSRF can indeed be checked on an ajax post request. I wanted to make sure someone on their own site isn't hitting my ajax endpoint with any success of doing anything, especially for another user.
However, I ran into a Laravel order of operations issue, with the way Laravel sets up the session. I was trying to call a validation method (within in the same class) in the constructor, where I validated for CSRF and verified the requesting user all in one place. I wanted to do this so that any time someone hits this class, I didn't have to call the verification in each public method in the class, I'd only have to call it once.
However, csrf_token(), and the request session in general, is not available to me yet in my construct. It is, however, available to me in the method within the controller class that is called in the route.
For example, given the following route:
Route::post('/test', 'AjaxController#test');
If I injected Request into the construct and then tried to reference anything in the session (in the construct), or get the value of csrf_token(), it will throw an error, because Laravel hasn't set that stuff up yet. But if I reference either of those things in the test method, it'll be there and available just fine.
A bit of a weird Laravel order of operations issue.
csrf protections are managed by Laravel Forms. It won't be available when dealing with APIs.
You should have a look at how middlewares are used in Laravel
https://laravel.com/docs/5.4/middleware
Think using API middleware for your APIs ;)
If you run this command php artisan make:auth documented here https://laravel.com/docs/5.4/authentication#authentication-quickstart when going to resources/views/layouts/app.blade.php you'll see this:
<meta name="csrf-token" content="{{ csrf_token() }}">
And in app.js
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN':$('meta[name="csrf-token"]').attr('content')
}
});
In 5.3 there was this cool feature which looks as though it has since been removed in 5.4.
<script>
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>
</script>
So what you need to do is add the csrf field to every request. Do the first 2 code snippets and you'll be fine. The 3rd I believe is probably for Vue.
Answer to your question: no, no, no and no. CSRF tokens I wouldn't believe are generated in POST requests, it's a Cross site Reference token, not an authentication token. If you're looking for something like authentication token refreshing then checkout JWT although the packages for JWT for laravel are a bit unfinished at the moment; with a little work you can get them working.
https://github.com/tymondesigns/jwt-auth 1.0.*#dev is pretty good. You can then use their refresh middleware to generate new tokens on request but this is quite advanced and unless it's for authentication then I wouldn't bother really.
I believe Dingo (another work in progress I believe) https://github.com/dingo/api uses the above package
Anything else let me know!

Route::resource does not support auth:api

I use passport for api authentication and i configure auth.php api gaurd to passport. Some of my route APIs are in auth:api group. I send Authorization header with access token and it check user very well.
But the problem is that, this mechanism works well in Route::post method and \Auth::user()->id return user id,
but in Route::resource \Auth::user() returns null.
I double checked everything and it seems Route::resource ignore "auth:api" middleware. I also tested middleware in __construct method of my resource controller. Nothing changed. Thank you for further help.
Route::group(['middleware' => ['auth:api']],function (){
Route::post('update',['uses'=>'C_Update#handle']);
Route::resource('contacts','C_Contacts',['only'=>['index','store','update','destroy']]);
});
At last i found a solution. The problem was because of __construct method. The Authenticated user hasn't been Authorized in construct method yet (I don't know why and if someone knows please tell me). So unfortunately I put \Auth::user in CRUD functions of my route.

Categories