I'm new to laravel and making a web service that can function without javascript (if a user has it disabled or something.)
But it would be a better user experience to be able to perform certain actions without refreshing the whole page. I'd like to be able to say, send a form without reloading the page, or refresh notifications.
The options I can think of are:
1) Send the ajax to the same route as the pure html form, but with an extra variable and make my laravel respond with json when that variable is detected
2) Use the API route? Will this detect the currently logged in user?
3) Make new routes for everything ajax, even though they function the same as my current routes (aside from returning a view)
Also, does the CSRF token work multiple times in a row, or do I need to disable that to handle multiple ajax form posts in a row without page refreshes?
I recommend keeping the routes separate, both to prevent weird caching bugs and for your own sanity as the code changes over time.
Laravel is set up out of the box to let you define web routes in routes/web.php and api routes in routes/api.php. Routes defined in your api.php file will be available at /api/* by default. It's much easier to manage changing the application this way, rather than trying to make your controllers do both views and api responses.
With Laravel Passport, your API routes can detect the currently logged in user via the auth:api middleware when combined with adding the Laravel\Passport\Http\Middleware\CreateFreshApiToken to your web middleware group.
https://laravel.com/docs/5.7/passport#consuming-your-api-with-javascript
An easy way to manage the duplicated controllers (one for web and one for api) is to put Api controllers in their own namespace, with php artisan make:controller Api/FooController. You can even set up your Api routes to look for controllers in this namespace by default by editing RouteServiceProvider.php.
Related
I've Blog website where all user can post Blog.I have learned about Gates,Policy and Middleware .Please come to know that i am using Auth() Default Authentication Process in Laravel. I want to protect user (A) blog from other users.
Now I have many things to handle this.
Using Auth if(Auth()->user->id==$blog->user_id)
Using Gate if(Gate::Allow('blog_protection',$blog))
Using Policy if(Auth::user()->cant('blog_protection',$post))
Using Middleware $this->middleware('blog_access')
Please tell if i am wrong Meaning of that functions then what is best method to handle this request for more reusable . Many Thanks In Advance.
I would consider writing a policy class for blog model resource. Multiple reasons :
You can list all access methods related to blog in one file to easy to track
You can do just $this->authorize('access_method_name', Blog::class) in controller
You can pass extra arguments to the method to filter it conditionally
If you have a method outside controller and you need to add filter(ideally the controller authorize() would filter it out) but still you can use
$user->can() or $user->cant()..
which will internally use the same policy.
Also to mention you can use this in blade directives #can()...# endcan #cannot...#endcannot
Middleware is something which would intervene in every request specified in the route group or all requests if its registered as global middleware group. If you want an access filter applicable globally in all routes then middleware is a better option. But for specific resource, I would prefer policies.
In short middleware for request filtering and handling whereas Policy for managing granular level access controls.
How can i make post request from another server to my laravel server?
I have a website from another provider (lets say domainA.com) , they have CMS system, so I can make my custom pages - the question is, I want to make a form in domainA.com, and post it to domainB.com (my original Server), how can I make it in laravel? As far as I understand I should use api route file for this, is it secure to make such a POST request? because as far as I understand there is no token protection on api requests right?
sorry for my english - i am most interested in security side of such a action - if you show me an example, it would be appreciated.
Laravel 5.4 has 2 route groups: web and api
the web group is used for all requests that come from the current laravel application. Laravel uses a csrf token with every request to make sure every request is coming from the own page to prevent cross site scripting.
the api group is for requests that a fired from an external server. For this group the csrf protection is disabled.
Remember: csrf protection ONLY checks if the requests is from your site, it does not handle the authentication or authorization.
To secure your API you can use json web tokens (jwt). There is a package that will handle the authentication parts for APIs.
If you want to keep it really simple you can write a middleware for all api calls, that is checking if the requests has a special value (your personal token) to give access to the api.
It's possible to accept post request to a Laravel Route and you can define route any of web.php or api.php route file but below are the differences.
web.php
Routes in Web.php will prevent the form without CSRF Token.
to avoid that you can add the route in VerifyCsrfToken.php file in except Array.
api.php
Routes will work directly but the api URL will be Example.com/api/<route>.
But for security you can share an Access Token for the routes and in the controller you can verify the requests with the access token and allow post.
You are right is not sure about this communication.
What you can do is a chain token code
Start with a code and every time you contact the server b it will give you a new code that you will need to use for the next message.
I know it's not as beautiful as a solution but I do not think of anything else.
You could implement your api framework but you would spend a lot of time
The documentation doesn't talk much about logging in and out and handling security in general.In Symfony, you can secure pages of your site via a YML file. Does F3 have anything like that?
What is the recommended way to secure pages and handle a logged in user? I liked basic Auth, but it isn't very flexible, and it seems logging out is trickier. So I decided to set up a form for login/logout.
I would have assumed that Auth automatically creates a session, but from what I can tell it doesn't. So does that mean I need to manually do it?
Also, how do I block non authenticated visitors from the site? Do I need to add a SESSION check in each route?
The freedom when using F3 is that you can/must implement this on your own.
You got multiple options here or can create some other creative solutions too, if your project requires it. The included Auth plugin doesn't create a SESSION of course, because it cannot know if you want to use a SESSION to track your users or maybe use other solutions (cookie, JWT, etc).
So in most cases you need to create an Auth controller where you check if a user is logged in or not - here you would probably use the Auth plugin and create the SESSION if you want that. From there on you got serveral other options.. just to name a few:
use a base controller, that your other controllers will extend (or a Trait) and add a beforeroute there, where you'll check if the user is logged in and allowed to access that ressource.
check the user rights in the front controller (index.php) and don't even register the routes that the user has no access to.
use a 3rd party plugin to add access checks to routes, i.e. f3-access
use another middleware router to pre-flight the current request and add auth checks to multiple routes at once
The problem
When displaying HTTP error pages (404, 500 and so on), I want to keep the standard design of my current project, including header and footer. My project also includes a registration system. When a user is logged in and receives an error message, he will be redirected to the corresponding error page, but Laravel does not recognize that the user is logged in. That's because custom error pages (located in resources/views/errors/{code}.blade.php don't run through the normal web middleware (for some reasons).
This behavior was already reported a few times, but no sufficient answer was provided. A hacky solution is to set the StartSession middleware to be applied on every request, but this isn't sufficient in my case.
How can I use the Auth/Session middleware on custom error pages anyway?
Solutions that do not fit
I don't want to add the StartSession middleware (or any other) to every request
Related questions and links
Laravel Auth in error pages, Laravel 5.0 custom 404 does not use middleware -> Solution is not wanted
Laravel 5.2 Auth::check() on exception pages (layouts) No good solution
A GitHub issue I opened, because I think that this behavior is not intentional
In coherence with the discussion around the github issue I've opened, here are the two best practices:
Adding the StartSession middleware to the global middleware list is a good pratice, as long as your app doesn't have an API or similar
In the second case, you can query the needed Frontend elements that are influenced by the session (e.g. login/register or profile buttons) by using jQuery and an AJAX call. So you are calling a route where middleware is applied and getting therefore the correct elements. A good example can be found in the GitHub issue I've linked.
I drew up this flowchart to explain but its all over complicated.
I just cant wrap my head around how this will work.
Front end : Server 1 - Angular2
Back end : Server 2 - Laravel 5.3
At the moment the back end has an auth token enabled with the passport.
I can fetch and send any info where I enable the Middleware API.
But how do I set up a Middleware API for the front end of the website to access and
a different one for user profiles?
Or do I not require this? Do I just render all data requested from the site in JSON and
make the Angular2 front end render it. Then with the Authentication when a user logs in
send back a token instead of a session.
I would love if anyone knows of any tutorials of Laravel 5.3 back end with
Angular2 front end on another server.
Well, the correct workflow in you case would be:
A user logs in, you send a request to the laravel server requesting a token
This token is stored in the session and will be used for future requests.
Angular will render the responses based on the requests made.
So, you say:
But how do I set up a Middleware API for the front end of the website to access and a different one for user profiles?
Well, because they are on different server, the view on this case will be rendered just by angular, you should find a way to make permission so the UI will know what to dow. In this case, you can not put an auth middleware to "block" access to the view, because the view will be rendered by a different thing other than larave.