Laravel 5.4: how to protect api routes - laravel

I have a react app that fetch datas from laravel api defined like so in routes/api.php:
// this is default route provided by laravel out of the box
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
// ItemController provides an index methods that list items with json
Route::resource('items', 'Api\ItemController', array('except' => array('create','edit')));
// this is to store new users
Route::resource('users', 'Api\UserController', array('only' => array('store')));
for example http://example.com/api/items returns the data as intended but it's really insecure since anyone could access it through postman.
How to make those routes only accessible inside the app?
As I'm new to it I don't understand if I need to set up api_token and how?
Do I need to setup Passport?
Is is related to auth:api middleware?
It may sounds really basic but any help or tutorial suggestions would be greatly appreciated
EDIT
End up with a classic session auth. Moved routes inside web.php. Pass csrf token in ajax request. Actually i didn't need a RESTful API. You only need token auth when your API is stateless.

As you are using Laravel 5.4 you can use Passport, but I haven't implemented yet, but i implemented lucadegasperi/oauth2-server-laravel for one of my laravel projects and it was developed in Laravel 5.1
Here is the link to github repository
lucadegasperi/oauth2-server-laravel
Here is the link to the documentation Exrensive Documentation
Just add the package to the composer json and run composer update,the package will get installed to your application , once installed add the providers array class and aliases array class as mentioned in the Laravel 5 installation part of the documentation,
you have to do a small tweak in order to work perfectly cut csrf from $middleware array and paste it into $routeMiddleware array and again run php artisan vendor:publish after publishing the migrations will be created and run the migration php artisan migrate
if you only want to secure api routes for each client like ios, android and web you can implement Client Credentials Grant, or if you need to every user with oauth the you can implement Authorization Server with the Password Grant or some other.,
Never use the client id or other credentials, generating access token in the form, but add it some where in helper and attach it in the request to the api,
Hope this answer helps you.

You could use JWT it's pretty easy to get it to work. You basically generate a token by requesting Username/Password and passing that token in every request that requires authentication, your URL would look like http://example.com/api/items?token=SOME-TOKEN. without a proper token, he doesn't have access do this endpoint.
As for
How to make those routes only accessible inside the app?
If you mean only your app can use these requests, you can't. Basically the API doesn't know who is sending these requests, he can only check if what you are giving is correct and proceed with it if everything is in order. I'd suggest you to have a look at this question

Related

How to register on Jetstream via Postman (API)

First step: I am posting data via Postman on the api/reg
Second step: I am getting perfectly all the sent data
Third step: nothing lol, I can't get to this 3rd step, what to do to send this data to database how Jetstream does?
Somehow I found this CreateNewUser.php and via dd() I found out that my regular blade register information is coming to this point, but from where is it coming, and where is it going after is a mystery, There is no any information on the internet, so I am getting the register data (name,email...) in my Laravel project, somewhere AGAIN in my Laravel project there is some mechanism that upgrades (adds tokens etc...) and sends my data to database, how to connect that two things to each other? Thanks in advance
Jetstream is not intended to be used in this manner, if you want to expose an API you should use something like Laravel Sanctum or Laravel Passport. Sanctum is more lgihtwieght and has simpler workflow, Passport is heavier and provides a full oauth workflow which might be overkill in some scenarios. Both of these solutions use token authentication with Jetstream does not provide out of the box.
That said, to answer you question of how this all works.
Jetstream uses Laravel Fortify as its web authentication provider. It comes with a bunch of routes predefined, all of which you can see using php artisan route:list --compact. The route you're interested in is the POST /register route which is mapped to Laravel\Fortify\Http\Controllers\RegisteredUserController#store. When the registration form is submitted, the data is sent to that controller/method. The method expects two parameters, a Request object and a CreatesNewUsers object, both of which are injected by Laravels IoC service container.
The CreatesNewUsers object that is passed to the store method, is an instance of the CreateNewUser class you've found in App\Actions\Fortify which then performs the action of registering a new user. If you were to modify the structure of your User class, such as adding a phone number for example, you would need to edit CreateNewUser to include that new requirement if it was required when a user registers.
Here is a nice tutorial on how to Build a Restful API in PHP with Laravel Sanctum.

How to protect laravel api route from outside access but allow unrestricted access if request comes from frontend?

I'm building the backend with laravel and then using Vue as front-end. Data is accessed over api calls using axios. Now I have this relatively simple task but I can't seem to find the proper solution. I want one of the routes to be easily consumable by Vue compoenents without the need to log in, however I don't want that route to be publicly available for anyone to use.
Things I have tried:
Using passport to protect my routes and then use passport's CreateFreshApiToken middleware. Protection works fine, unauthorized users are not able to access the routes, however I don't get laravel_token in my cookies and therefore I can't get access to that route if I'm not logged in.
Use passport's client credentials grant access. Works fine and the way I want it to work but doesn't really make sense because if I hardcode the client_secret - anyone can access it and then use it to access protected routes. If I make a proxy-like solution, to call a controller method, which would issue a valid token and thus not exposing client_secret to front-end but then anyone could just call that route which issues the token and it would be pointless once again.
Apparently the answer is pretty simple and I was overcomplicating things. I don't know if this is the right/elegant way to do this but basically. If you don't need your api to be accessible from other applications (which I didn't) we can just put routes in web.php instead of api.php. This will ensure that web middleware is used and so it will use the basic csrf token validation, which is totally sufficient for protection against outside requests. You can also leave the route in api.php and just use web middleware on that route. The outcome is exactly what I needed - application is getting data over a route without any need to login AND that route is not available over postman or anything else.

Laravel API Auth with Passport and React

I have a Laravel 5.5 Application that's using the session based auth out of the box. On some of these pages I have react components that need to get/post data from/to an API.
What is the best practice for handling this? Do I simply hide the API endpoints behind the auth? This would work but should I be using Laravel Passport for this instead?
I've had a play with Passport and it seems that this would work but I don't need users to be able to create clients and grant 3rd party applications permission etc. There is just the first party react app consuming the data from inside the laravel application (view).
From my initial experimenting with it, it seems I'd need to have the login call made first to receive an access token to then make further calls. As the user will already be authenticated in the session is there an easier way?
I'm not sure if Passport is intended to be used for this purpose or not. I'd rather take the time to get it right now as I'd like to get the foundations right now if the app scales.
You can proxy authentication with Passport. Using the password grant type users would still log in with their username/password, then behind the scenes make an internal request to Passport to obtain an access token.
Restrict what routes are available when registering in a service provider by passing in:
Passport::routes(function ($router) {
$router->forAccessTokens();
$router->forTransientTokens();
});
That limits access to personal tokens and refresh tokens only. A client will be created when you run php artisan passport:install.
Setup a middleware to merge the password grant client id and secret in with the request, then make a call to the authorization endpoint. Then it's just a matter of returning the encrypted token and observing the Authorization header for requests to your api.

Laravel 5.4 use JWTauth along with normal authentication

Me and my friend are creating an application. I'm using Laravel 5.4 as the backend and he uses Angular2 as frontend.
The Laravel project serves as a rest API with JWTauth token authentication.
Now I would like to make a small backend dashboard in the Laravel project that is only accessible by admins.
How would I go about using different authentication (with session) instead of tokens when I just browse to the api backend part?
This is pretty straightforward. Just apply the JWT auth middleware to the API routes and the normal auth middleware to your admin dashboard. You don't even need to tweak anything since JWT doesn't need changes to your table structure or need for changing the existing auth.
Build the backend dashboard using the built int auth scaffolding using the auth and guest middleware. For the api routes use the standard api middleware along with the jwt.auth middleware if you're using the tymondesigns/jwt-auth package. There will be no conflict with these two.
Bro use separate guard like
$loginUser = Auth::guard('web')->loginUsingId(12,true);

How to get the csrf token "outside" laravel view?

i have a cordova app connected to a laravel api.
I need to make a post from the mobile app to that laravel, but i need the csrf token.
I cannot do the {{csrf_field}} because the view i´m using in the mobile is not provided by laravel so no blade or laravel helpers.
I tried doing a previous ajax call only to get the token, but i don´t know if this is the best way to do it.
Thank you!
In your case I wouldn't recommend to you to get the CSRF token.
Instead I'd suggest you to construct a personal authorization code (per user) or removing the corresponding URLs from the CSRF check (maybe even the whole API).
The token is linked to the currently authenticated user. What you're trying to do won't work.
Try using the API middleware to login and store the token on the mobile app, and use that to identity yourself.
While as the other answers have said, this isn't a recommended solution for your problem, Laravel has a helper function to give you the CSRF token, aptly named csrf_token().
It's listed on the helpers page of Laravel's documentation: https://laravel.com/docs/5.4/helpers#method-csrf-token

Resources