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.
Related
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.
I'm looking to find the best way to implement site-wide authentication checking in Laravel 5.4
I'm building a website that has a growing number of pages that check for rows in a database assigned to a user. If someone visits a page on the site that carries out this function, and they are not logged in, Laravel will give
"Trying to get property of non-object"
and display its error page.
I need to remove all Laravel error pages from my project, to clean it up, and I'm starting with these errors:
Current solution:
My current solution is that wherever a route makes these checks in a controller, I wrap it in
if (Auth::check()) {
I'm wondering if there is a better solution other than wrapping all such code in this?
Edit
I need to go and learn how middleware works.
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
We have eZPublish 5. The authentication is handled by User kernel module kernel/user/login.php. This PHP script is called when trying to access a siteaccess which requires authentication.
Example scenario:
When trying to access http://example.com/marketing
it redirects me (when not logged in) to http://example.com/marketing/user/login
Which is expected behaviour.
What I would like to achieve is to rewrite the kernel/user/login.php file and preferably keep the url the same (this is not mandatory).
I need to do this because I need to integrate Duo Security Multifactor Authentication, so I need to handle the logging in in a custom way.
So on the first page I need to display the login form, then when it is submitted I need to verify if credentials are correct (but not log in the user at this phase) then I need to return another view where an iframe is present for the second authentication, and when the second authentication is successful only after that I can login the user and redirect him/her to the desired page.
Is there any way how to do this? I tried to create an extension with a module user and view login.php but it doesn't worked - the User kernel login.php is executed always when http://example.com/marketing/user/login is hit.
I am trying to do this for several days now but no luck and I'm out of ideas.
Thanks in advance for any help.
Welcome to the eZ Community!
What you want / need is both possible and quite simple to implement :)
First based on your description I recommend the following:
https://github.com/brookinsconsulting/bckernelmoduleoverride
Note: We forgot to package and release this extension some time ago but have been using it as part of our open source ezpedia.org code base. We thank you for reminding us and prompting us to package the code for individual usage.
Concerning double authentication we did something similar but actually quite different with this solution:
https://github.com/brookinsconsulting/bcconfirmpassword
Now code sharing aside. You may want to first study the login handler system which provides for many forms of custom user authentication system. https://en.ezpedia.org/en/ez/login_handler
Yet from your description and some intuition on our part it truly sounds like without more information that you very well do need to both override the default user/login module view (what we call a kernel module view copy override; copy the default module and customize the code within an extension module). We have done this -a lot- for special customer use cases and it's not very hard.
Most of the time the hard part is getting all the module and module view identifiers to not conflict once within an module extension and we think that will be less of a problem for you if you simply use / leverage the bckernelmoduleoverride extension which provides for using default kernel modules and module views customized within a module view extension.
Please feel free to ask further questions or share more information about your custom authentication system your trying to integrate. Frames in this day and age sounds like a painful system to be required to implement for a secondary authentication system.
We hope this helps!
Note: This thread is cross posted from: http://share.ez.no/forums/ez-publish-5-platform/ezpublish-5-custom-user-authentication-multifactor
I have implemented a CSRF protection for my custom TYPO3 extension (according to the documentation) and it's working nicely for non-authenticated frontend visitors and also for backend admins in frontend. A strange thing I noticed is that an error is thrown, if an non-admin backend user tries to use a form in a frontend plugin:
PHP Catchable Fatal Error: Argument 1 passed to TYPO3\CMS\Core\FormProtection\FormProtectionFactory::getMessageClosure() must be an instance of TYPO3\CMS\Lang\LanguageService, null given
I tested using TYPO3 V. 7.6.10 and 7.6.14. The error occurs in both versions.
I took a look at the source code in the FormProtectionFactory and it seems that $GLOBALS['Lang'] is initialized for admin users in the FE, but empty for normal backend users. In BE, both user groups can access other CSRF protected forms.
According to the official reference of the LanguageService, the LanguageService is usually only available in BE:
This class is normally instantiated as the global variable $GLOBALS['LANG'] It's only available in the backend and under certain circumstances in the frontend
Does anyone know what these certain circumstances are? It is of course possible to log off from BE and visit the forms as an unauthenticated user, but this is obviously very annoying. I think that this is expected behaviour, but I don't understand why the issue only occurs for non admins. Maybe someone has an idea, how to make the form available for non-admin backend users in FE, too?
Any help is highly appreciated.
Thanks!
For the sake of completeness, my invocation of the CSRF token generator, but I think that the 'issue' is in TYPO3 itself (or is expected behaviour):
$this->view->assign("csrfToken", FormProtectionFactory::get()->generateToken($this->extensionName,
$this->controllerContext->getRequest()->getControllerActionName(), $additionalObject));
The TYPO3 devs think that CSRF only applies to users-that-are-logged-in, which is not the case here, and thus CSRF functionality cannot be used at all in the frontend for anonymous users.
See https://forge.typo3.org/issues/77403