Api routes not working in laravel 5.4 - php

I am trying to call an api route from postman like this
http://project.app/api/someroute
But it does not work and through that error
file_put_contents(/home/vagrant/Code/project/storage/framework/cache/data/a0/c6/a0c65d98bc6f1fe2c35f8ba5fd47c8a3e225165e): failed to open stream: No such file or directory

Create this directory manually:
/storage/framework/cache
Also, make sure you have:
/storage/framework/views
/storage/framework/sessions
Usually, you'll also need to set the right permissions on the storage directory:
chmod -R 755 storage

Couple things to check
1) Make sure you add an api_token column to your users database.
$table->string('api_token', 60)->unique()
2) Add a random 60 character string to that column
3) Add a route to your api.php routes file
Route::group(['prefix' => 'v1', 'middleware' => 'auth:api'], function ()
{
Route::get('test', function(){
return ['name' => 'zechdc'];
});
});
Notice I added a prefix of v1. Looks like laravel already adds an 'api' prefix as well.
4) Visit your url and append your api_token you created for a user. You should see some JSON on your screen at this point.
http://localhost/api/v1/test?api_token=wwfaadmcmsvbtldzxlenjxhxakwyriwhrxcbkgfpnlccyhhxexvzfixxjtjq
Source: https://laracasts.com/discuss/channels/laravel/53-api-routes-auth-middleware-confusion?page=1

Related

PermissionManager for Backpack Laravel -> I want to protect the Routes to Users that only can Edit Permissions

I made this in:
/vendor/backpack/permissionmanager/src/routes/backpack/permissionmanager.php
Route::group([
'namespace' => 'Backpack\PermissionManager\app\Http\Controllers',
'prefix' => config('backpack.base.route_prefix', 'admin'),
'middleware' => ['web', backpack_middleware()],
], function () {
Route::group(['middleware' => ['can:edit permissions']], function () { <---- I added this code
Route::crud('permission', 'PermissionCrudController');
Route::crud('role', 'RoleCrudController');
Route::crud('user', 'UserCrudController');
}); <---- I added this code
});
It doesn't work
But I know is not a good idea to do it like this, touching the vendor folder
How can I handle this situation?
Also I've tried to put that code inside the routes of Backpack (/routes/backpack/custom.php), with no results
Indeed, changing things in the vendor directory is a big no-no. But you can easily do the same in your app. You can see in this package's docs, under overwriting functionality that there's an easier solution for that:
Create a routes/backpack/permissionmanager.php file. Then Backpack will load YOUR file, instead of the one in the package.
Remember to include ALL routes from the vendor file and all your overwrites too. The file in the vendor will no longer be used.

Laravel 8 Routing Redirect to blank page [duplicate]

In my routes.php I have:
Route::patch('/preferences/{id}', 'UserController#update');
And in the view file (account/preferences.blade.php) I have:
{!! Form::model(Auth::user(), ['method' => 'PATCH', 'route' => '/preferences/' . Auth::user()->id]) !!}
But I'm getting this error:
Route [/preferences/1] not defined
A similar error occurs when calling the route() helper directly:
route('/preferences/' . Auth::user()->id');
I think I'm misunderstanding the docs on this topic but I've defined a route for PATCH requests with a given parameter, and set this in the view correctly. What am I overlooking here?
The route() method, which is called when you do ['route' => 'someroute'] in a form opening, wants what's called a named route. You give a route a name like this:
Route::patch('/preferences/{id}',[
'as' => 'user.preferences.update',
'uses' => 'UserController#update'
]);
That is, you make the second argument of the route into an array, where you specify both the route name (the as), and also what to do when the route is hit (the uses).
Then, when you open the form, you call the route:
{!! Form::model(Auth::user(), [
'method' => 'PATCH',
'route' => ['user.preferences.update', Auth::user()->id]
]) !!}
Now, for a route without parameters, you could just do 'route' => 'routename', but since you have a parameter, you make an array instead and supply the parameters in order.
All that said, since you appear to be updating the current user's preferences, I would advise you to let the handling controller check the id of the currently logged-in user, and base the updating on that - there's no need to send in the id in the url and the route unless your users should need to update the preferences of other users as well. :)
This thread is old but was the first one to come up so I thought id share my solution too. Apart from having named routes in your routes.php file. This error can also occur when you have duplicate URLs in your routes file, but with different names, the error can be misleading in this scenario. Example:
Route::any('official/form/reject-form', 'FormStatus#rejectForm')
->name('reject-form');
Route::any('official/form/accept-form', 'FormStatus#acceptForm')
->name('accept-form');
Changing one of the names solves the problem. Copy, pasting, & fatigue can lead you to this problem :).
If route is not defined, then check web.php routing file.
Route::get('/map', 'NavigationController#map')->name('map'); // note the name() method.
Then you can use this method in the views:
<a class="nav-link" href="{{ route('map') }}">{{ __('Map') }}</a>
PS: the __('Map') is to translate "Map" to the current language.
And the list of names for routes you can see with artisan command:
php artisan route:list
I'm using Laravel 5.7 and tried all of the above answers but nothing seemed to be hitting the spot.
For me, it was a rather simple fix by removing the cache files created by Laravel.
It seemed that my changes were not being reflected, and therefore my application wasn't seeing the routes.
A bit overkill, but I decided to reset all my cache at the same time using the following commands:
php artisan route:clear
php artisan view:clear
php artisan cache:clear
The main one here is the first command which will delete the bootstrap/cache/routes.php file.
The second command will remove the cached files for the views that are stored in the storage/framework/cache folder.
Finally, the last command will clear the application cache.
when you execute the command
php artisan route:list
You will see all your registered routes in there in table format .
Well there you see many columns like Method , URI , Name , Action .. etc.
So basically if you are using route() method that means it will accept only name column values and if you want to use URI column values you should go with url() method of laravel.
One more cause for this:
If the routes are overridden with the same URI (Unknowingly), it causes this error:
Eg:
Route::get('dashboard', ['uses' => 'SomeController#index', 'as' => 'my.dashboard']);
Route::get('dashboard/', ['uses' => 'SomeController#dashboard', 'as' => 'my.home_dashboard']);
In this case route 'my.dashboard' is invalidate as the both routes has same URI ('dashboard', 'dashboard/')
Solution: You should change the URI for either one
Eg:
Route::get('dashboard', ['uses' => 'SomeController#index', 'as' => 'my.dashboard']);
Route::get('home-dashboard', ['uses' => 'SomeController#dashboard', 'as' => 'my.home_dashboard']);
// See the URI changed for this 'home-dashboard'
Hope it helps some once.
My case is a bit different, since it is not a form but to return a view. Add method ->name('route').
MyView.blade.php looks like this:
CATEGORIES
And web.php routes file is defined like this:
Route::view('admin', 'admin.index')->name('admin');
i had the same issue and find the solution lately.
you should check if your route is rather inside a route::group
like here:
Route::group(['prefix' => 'Auth', 'as' => 'Auth.', 'namespace' => 'Auth', 'middleware' => 'Auth']
if so you should use it in the view file. like here:
!! Form::model(Auth::user(), ['method' => 'PATCH', 'route' => 'Auth.preferences/' . Auth::user()->id]) !!}
In my case the solution was simple:
I have defined the route at the very start of the route.php file.
After moving the named route to the bottom, my app finally saw it.
It means that somehow the route was defined too early.
On a side note:
I had the similar issues where many times I get the error Action method not found, but clearly it is define in controller.
The issue is not in controller, but rather how routes.php file is setup
Lets say you have Controller class set as a resource in route.php file
Route::resource('example', 'ExampleController');
then '/example' will have all RESTful Resource listed here:
http://laravel.com/docs/5.0/controllers#restful-resource-controllers
but now you want to have some definition in form e.g: 'action'=>'ExampleController#postStore' then you have to change this route (in route.php file) to:
Route::controller('example', 'ExampleController');
Please note that the command
php artisan route:list
Or to get more filter down list
php artisan route:list | grep your_route|your_controller
the forth column tells you the names of routes that are registered (usually generated by Route::resource)

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 unexpected redirects ( 302 )

I have started a new Laravel 5.2 project, using laravel new MyApp, and added authentication via php artisan make:auth. This is intended to be a members only website, where the first user is seeded, and creates the rest (no manual user creation/password reset/etc).
These are the routes I have currently defined:
Route::group(['middleware' => 'web'], function () {
// Authentication Routes...
Route::get( 'user/login', ['as' => 'user.login', 'uses' => 'Auth\AuthController#showLoginForm']);
Route::post('user/login', ['as' => 'user.doLogin', 'uses' => 'Auth\AuthController#login' ]);
Route::group(['middleware' => 'auth'], function() {
// Authenticated user routes
Route::get( '/', ['as'=>'home', 'uses'=> 'HomeController#index']);
Route::get( 'user/{uid?}', ['as' => 'user.profile', 'uses' => 'Auth\AuthController#profile' ]);
Route::get( 'user/logout', ['as' => 'user.logout', 'uses' => 'Auth\AuthController#logout' ]);
Route::get( '/user/add', ['as' => 'user.add', 'uses' => 'Auth\AuthController#showAddUser']);
[...]
});
});
I can login just fine, however I'm experiencing some very "funky" behavior - when I try to logout ( via the built-in logout method that was created via artisan ), the page does a 302 redirect to home, and I am still logged in.
What's more, while almost all pages (not listed here) work as expected, user.add also produces a 302 to the home page.
Do note the homepage is declared to the AuthController as $redirectTo, if that makes any difference
I found out about the redirects via the debugbar. Any idea on what to look for ?
I got the same issue and i solved it by adding the header with accept:'application/json'. And I think I checked the source code before which indicates that if you don't add this, it might redirect when you are using the auth middleware. But I am not sure if it is the case and I cannot recall where i found this.
After several hours of hair pulling, I have found my answer -- and it's silly.
The problem is that the route user.profile has a path user/{uid?} and it matches both user/logout and user/add as paths.
It being before the others, and not having a regex or similar, it handled the route.
I still don't know why a 302 was generated for that page, but found that moving it out of the AuthController and into the UserController (where it should be from the start) fixed the behavior.
Thus, my (amended and working) routes now look like so:
Route::group(['middleware' => 'web'], function () {
// Authentication Routes...
Route::get( 'user/login', ['as' => 'user.login', 'uses' => 'Auth\AuthController#showLoginForm']);
Route::post('user/login', ['as' => 'user.doLogin', 'uses' => 'Auth\AuthController#login' ]);
Route::group(['middleware' => 'auth'], function() {
// Authenticated user routes
Route::get( '/', ['as'=>'home', 'uses'=> 'HomeController#index']);
Route::get( '/home', ['as'=>'home', 'uses'=> 'HomeController#home']);
Route::get( 'user/logout', ['as' => 'user.logout', 'uses' => 'Auth\AuthController#logout' ]);
// *** Added /profile/ here to prevent matching with other routes ****
Route::get( 'user/profile/{uid?}', ['as' => 'user.profile', 'uses' => 'UserController#profile' ]);
Route::get( '/user/add', ['as' => 'user.add', 'uses' => 'UserController#showAddUser']);
[...]
});
});
I encountered an issue with 302 Redirects when posting ajax requests. The solution in this case was to remember to include the CSRF token.
See the Laravel 5.4 documents here: https://laravel.com/docs/5.4/csrf
For me it was guest middleware!
This middleware redirects user to homepage if authenticated.
You don't have to use it for Api requests. So I removed it and the problem solved.
May be default redirect page after logout is home and seems like you do not have home in your web route. Try the below code in your AuthController.php
use AuthenticatesAndRegistersUsers, ThrottlesLogins; // after this line
$redirectAfterLogout = 'login' // add this line
This will redirect you to login page after logout. You can change it to any route if you wish. I used login as an example.
OR
You can change after logout route in \vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
public function logout()
{
Auth::logout();
return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : 'login');
}
I changed the default route to login. If you don't have $redirectAfterLogout in your AuthController.php it will look here for redirect path. I don't suggest people to edit here, it's kind of hard coding.
I had this issue and it turned out I had a route:redirect inside my ajax controller.
which doesn't make sense because obviously we have to return ajax but I was returning a route!
I too experienced this issue in the login page which worked fine previously. So thought have a look at the directory permissions and it resulted the following:
drwxr-xr-x 7 user user 4096 Jun 27 2019 storage
So storage directory has 755 permission which means only the owner has write access, Since that directory owned by "user" others like laravel can't write into it.
Changing the directory to 777 with this cmd resolved my issue:
sudo chmod 777 -R PROJECT_PATH/storage
The right way,
Since making that directory world-writable isn't the right way, make that directory owned by apache and set 775 to storage.. and it worked again.
sudo chown -R user:www-data PROJECT_PATH/storage
sudo chmod 775 -R PROJECT_PATH/storage
I use a lot ajax (get & post) and with every response I update the token with session()->regenerate() on the server, then on the client side I update every token field with js.
But last week, I delete by mistake the one liner function to do that. So, suddenly the system starts to give a 302 response after the second call. It was so hard to find what was going on, because it works sometimes (firstime) and sometimes don't.
After I realize it was a token mismatch, I struggle a couple of days trying to find why, because the response don't point a token mismatch, just the 302 redirect.
Finally, I find the problem by dd() both tokens on the tokensMatch() function. I don't know why it won't trigger a TokenMismatch.
I hope this anecdote help you.
If your website doesn't use HTTPS you have to define the following attribute in your .env
SESSION_SAME_SITE=Strict
Note: this precaution applied by some browsers to prevent exploit website's users
For me it was this in my controller:
public function __construct()
{
$this->middleware('admin');
}
For me it was config/session.php
I changed some values there for production app like path, secure, same_site
But on local due to http://localhost, Secure session was failing to create any cookies.
That's why Authenticate middleware redirecting to login page with status 302
I have modified my login route with adding as parameter to it and it worked for me.
Route::get('login', ['as' => 'login', 'uses' => 'loginController#index']);
As for me encountered 302 status during saving and what fixed that was inserting
Accept: application/json on ajax header, because i hava a script inside the php file.
$.ajax({
url:'{{route('fetchMunCit')}}' +'/'+id,
type:'GET',
dataType:'json',
Accept: application/json
success:function(response)
In case somebody is experiencing this.
My case was that the APP_URL value is different from the actual URL hence I was getting 302 error.

Laravel make:auth problems, can't view the premade login or register page

I've created a laravel 5.2 project. I added a database, and some basic views and controllers (Note: I think this is my problem). I then ran the artisan make:auth command. It ran successfully. Despite me already having a login and home view and controller.
I can view laravel's premade 'home' page on my localhost. But once I click the login or register link, things break and I get,
"No supported encrypter found. The cipher and / or key length are invalid."
I've de-bugged this and insured my keys are correct and in the appropriate places.
This is my routes.php
Route::get('/', function () {
return view('welcome');
});
Route::group(['middleware' => ['web']], function () {
//
});
Route::group(['middleware' => 'web'], function () {
Route::auth();
Route::get('/home', 'HomeController#index');
});
I obviously have no route here for login or register, but shouldn't make:auth create routing behind the scenes? From what I've read, this should have worked out of the box. What am I missing here? Any help would be great,
Thanks.
Run
$ php artisan key:generate
I have resolved my problem.
I had originally set the key in my .env file to
APP_KEY=854uQ9...(random 32 bit key)
I had also set config/app.php to
'key' => env('854uQ9...(same 32 bit key as above)')
NOTE the missing ''APP_KEY''. Once I changed config/app.php back to
'key' => env('APP_KEY', 'SomeRandomString'),
the links worked. I can now change 'SomeRandomString' to my app key, but as the .env file is checked first, I assume this can be left as is.
Thanks for the replys.

Categories