Laravel 5.0 multiauth - php

I have an application which has two parts back-end, and front-end. In the back-end admin can log in, and in the front-end the client can log in. Now it has been implemented. All application's query is done by logged in user id in both admin and client end.
Now my app needs a functionality where admin can view client data as same as client see their profile.There are a lot of things in client end. I can you use Auth::loginUsingId($client_id). Here client profile is showing perfectly but admin loggin session is lost as expected.
How to achieve this while admin login remain and admin can see client full data?

Let me introduce the simpliest way to have login as client functionality. First, define asuser and returnback routes.
Routes and actions
Route::get('/asuser/{user}', 'AdminController#asuser')
->where('user', '[0-9]+')
->name('asuser');
Route::get('/returnback', 'ClientController#returnback')
->name('returnback');
In admin's controller:
public function asuser(User $client, Request $request) {
/* insert checking if user has right either here with some field
* like $user->is_admin or using middleware settings and Policy
*/
# who user is
$fromId = Auth::user()->getId();
# logging as a client
Auth::login($client, true);
# but keeping admin in a session
$request->session()->put('adm_id', $fromId);
return redirect()->route('some-client-route')
->with('status', 'You are logged in as a client');
}
And for returning back ClientController
public function returnback(Request $request) {
$fromId = Auth::user()->getId();
# getting admin id
$admId = $request->session()->pull('adm_id');
$adminUser = User::find($admId);
if (!$adminUser) {
return redirect()->back()
->with('status', 'Not allowed');
}
# logging out as a client and logging in as admin
Auth::logout();
Auth::login($adminUser, true);
return redirect()->route('some-admin-route')
->with('status', 'Welcome back!');
}
Is it ready for production
No, it's not. That's not a great solution, it's just a glimpse how to use it. Sessions have lifetime, so if admin doesn't return back in its lifetime, session variables are lost and he becomes a client (if remember me=true, as in the code above). You can store value not in a session but in a database column.
In addition as t1gor mentioned, you must pay attention to the fact that you can't log client's actions and send events when admin is a client. That's the most serious problem of logging as a client. Anyway, I suppose, it is easier to solve that, than to move all the auth logic out of the views.
Well, hope it is helpful.

I think a good way to manage client/user profiles is to implement an user management section at your backend, display and edit your users and their profiles there.

Laravel does not provide mixed sessions. You can only be authenticated as one user at a time. If you really need this kind functionality in Laravel 5.0 you could solve this by hackish user ping-pong (e.g. login temporarily as client and switching back to admin right after).
But it seems like your problem is more Authorization-related (in contrast to Authentication). Laravel implemented an authorization layer in v5.1.11. Since v5.0 is not supported anymore you should update regardless of this feature.
You can find more information about authorization in the official documentation: https://laravel.com/docs/5.1/authorization

I would rather suggest you separate the view logic e.g. business logic into some common layer rather then doing a "login-as-client" functionality. Even though it looks like a short-cut, you'll have a whole lot of things to think about.
For instance, how do you log application events now? Add a check everwhere that the session has a adm_id and log it instead of userId? This is just one example.
What I would have done:
Separate the view (e.g. user profiles, user content, etc.) from the session so that it is accessed by the ID in the URL or whatever else method, not by currently logged in user id.
Implement a propper role-based ACL. There are plenty of packages already. In your example, you wouold have an admin role and a client role, both havin permission object view-client-profile, for instance.
In the end, this might take a lot more time for development, but would defenitely save you some time debugging/troubleshooting with the angry client on the phone. Hope that helps.

I think middleware is the best possible option to filter the content between the admin and the normal user,because the code in the middleware run before any function call.
You just only need to set the usertype in the session and filter accordingly.
Visit:https://laravel.com/docs/5.4/middleware

Related

Symfony 5: How to make Login redirect to different pages deppending on role

I'm currently working on a inventory system with login for Admin and different units and what I need to make is the Login to redirect users deppending on their ROLE
I've read through the documentation and found loads of information but nothing I work on works.
I know the gist is to put an IF inside the onAuthenticationSuccess, and check the roles and redirect them accordingly, the problem is that I don't know how to retrieve the role after login.
I've tried checking isGranted, getRoles and the Custom APi suggestion on Symfony documentation.
Sorry if the post doesn't have the format, but I'm brand new to stackoverflow and quite new in PHP coding.
You can change the default target path for a login, see Changing the default page in the security documentation.
This will guide all your users to the same page after login. On this page you can perform a role check and display different content or redirect again based on their role. This might not be perfect - for example if you are not careful, you might get too many redirects in your browser - but it is probably the fastest and easiest way to solve your problem, because you can just use the helper methods in the Controller that you are probably more accustomed to.
If you want to already decide where to redirect your users while they login, you will need a custom Authenticator. See Step 3 in How to Build a Login Form to see how an Authenticator generally looks. You will then have to change onAuthenticationSuccess, e.g. something like this:
public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
// the $token holds the user object. You might have stumbled upon this in the context of the service `security.token_storage`
$user = $token->getUser();
if (in_array('ROLE_ADMIN', $user->getRoles(), true)) {
return new RedirectResponse($this->urlGenerator->generate('app_admin_dashboard'));
}
return new RedirectResponse($this->urlGenerator->generate('default_route'));
}
Be careful that the role check I do there, might not work when you use hierarchical roles, see: Hierarchical Roles.

Laravel - Master password / Log into other accounts?

I have developed a nutrition platform that I'm using with my clients. It's somewhat similar to MyFitnessPal.
Some of my clients need help refining their diets so I need to log into their account to make changes to their plan.
What's the best option to achieve this? I thought of maybe having a master password that lets me log into any clients account but I don't know how to implement this.
My postLogin() method in the LoginController doesn't seem to be doing anything.
In our applications we have a route/controller method in the admin backend that does something like auth()->login($user); then redirects you to the route the usual user would go to when they first login.
Docs:
https://laravel.com/docs/5.4/authentication#other-authentication-methods

Custom login controller in Symfony2

For the last two days I read through multiple resources on authentication in Symfony2. I think I understand most parts, however I feel that I do not understand the whole thing. I successfully created two authentication providers and a UserProvider but I don't understand how to customize the login process.
What I try to do is writing a REST API that will be consumed by a client that I also write. The client will display a form and sent the credentials via Ajax. Therefore, I don't want to use HTTP basic auth (I don't want a browser window to pop up), I don't want to use OAuth or any token (but use credentials) and I don't want to use a form_login (the login form is rendered by Angular).
Using my custom authentication provider, I can verify that a client is logged in, using a cookie I set in the login controller. However, I don't understand how I would login (or what logged in means in Symfony) a user if I'd try to use the session/Symfony security bundle. I could just avoid all security things from Symfony and roll my own implementation but I would prefer to understand how Symfony expects the authentication provider and the login controller to work together.
What I want is one route where a client can check if it is logged in, login and logout.
GET /session # return the session if it exists, or 401
POST /session { session: { email: testy#mctest, password: test1234 }} # login
DELETE /session # destroy session
How would I achieve this in a "Symfony" way?
(Bonuspoints for explaining the general authentication concept in Symfony, outside of the authentication provider)
I'll try to make it the more verbose and simplest that I can from what I personally know :-).
This is what I understood from when I implemented my own Security layer based on the Symfony Security component. If something is not right, please tell me and I will correct it to make it more accurate.
The Security component works with firewalls. A firewall defined a "zone" that is under the responsibility of the Security Component.
For each firewall, you would usually match a pattern that would be matched with the current request. If it matches, then the Security Component tries to determine if the request is allowed to access the resource.
In order to do this, the Security component is divided into two steps :
First : authenticate the user. If the user is not authenticated, we cannot authorize him. So the component will go through its Authentication Manager in order to authenticate the user. Authenticating a user in the Symfony way means trying to create a Token (which is actually juste an instance of the TokenInterface class) matching the current request that is going to be authenticated, and then try to authenticate it.
This Token is supposed to be created thanks to Authentication Listener(s) (classes implementing the ListenerInterface interface). For instance, one will usually use a UserProvider to set a User into the Token object.
Then, when the token is created, it doesn't mean that the Token is authenticated. This Token will be authenticated thanks to the Authentication Manager. An often use kind of Authentication Managers is based on providers that will check if the credentials (or something else) is wrong with the current token. For example, a DaoAuthenticationProvider will check if the password given with the token user matches with the one in what our users provider gives to us. If not, it fails : either another provider can authenticate the current token, or this will be an authentication fail.
http://symfony.com/doc/current/components/security/firewall.html
Second : authorizing the user. For this, I suggest you to read the chapter about it in the Symfony documentation online. You can find it here. It is based on an AccessDecisionManager that will decide if the current user, based on the authenticated token, is now allowed to access the resource. This is usually made thanks to classes called Voters that will vote in order to decide if a user is allowed to access the current resource.
A voter could vote no, another could vote yes, and another could vote I don't know. The final decision is made from the AccessDecisionManager that will, based on how it is configured, determine if these votes will either allow the user ("Any yes allows the user" or forbid him ("Any no is strict").
I think that this is the basis of what you should understand, to me, about the Security component. Keep in mind that it can be very tricky to understand first, especially for the Authentication part.
Last but not least, I highly recommend you to read this whole chapter : Here !. It is the key and your bible if you want to understand what's happening inside this tricky but awesome component.
Now, for your login issue : what would be useful for you is to check how to create your custom Listener (see the authenticating part of my answer) in order to create your own business logic of "how do I authenticate my user based on the current request". Your form would be an entry point of a firewall zone that would be then pointing to this firewall zone. This listener would check if the information provided by your form is inside the request, and then create the Token. Then, you would have a custom way to authenticate your token thanks to the information you provide.
(Sorry for my english !)

How can I combine CakePHP's Auth helper with a second authentication method?

I've been using CakePHP's Auth helper for a while now, and while it's been successful, recently I was asked to re-tool our system. We're to allow users to log in using their Active Directory credentials.
Actually authenticating users is easy, and I already have the code to do this. However, Auth itself is shrouded in mystery, and I haven't swam through it's source code yet. What I'd like to do is have the system attempt to authenticate using the standard Auth method, and if that fails, fallback on Active Directory and attempt to authenticate that way.
Database wise, I figure I'll need to modify my users table to store the Active Directory credentials in some way (something as simple as storing the AD username should suffice actually, since it's just a link) and then manually log that user in. Is there a way to just tell Auth that "Hey, I'm logged in as this user now" without doing a POST to login()?
The main reason I'm doing all of this is to avoid having to rewrite tons of code elsewhere in the project by switching away from Auth entirely. That may be a bad idea though, if I'm introducing some hidden insecurity that's going to bite me later.
Oh: We're using CakePHP 1.3. I'm not against upgrading the project to version 2.0, but I'll avoid it unless there's a good reason to.
I believe you can just call: $Auth->login($user); where $user contains the queried data. So if you have the Active Directory credentials associated with the user account record in the database, you can just do:
$user = $this->User->find('first', array('conditions' => array({ACTIVE RECORD SEARCH})));
$Auth->login($user);
and now you are logged in as that user.

Codeigniter: 2 Apps with one central login screen

I am writing an application in CodeIgniter and I have concluded that it's best to write two applications. One for back office and one for client use.
I would like to have just one login screen. It will be in the back office application but if a client user logs in then I want to redirect to the client app and create a session there. The database user table stores the user type i.e. client or admin.
I have come up with the following solution. As I want to this the correct way I said i'd run it by you guys to see what ye think.
User logs into admin CI app.
Admin CI app verifies user and determines type. If admin then go ahead and create session etc.
If the user is a client then MD5(user_ip+timestamp OR make a secure token some other way) and store in a token field (user_table) in DB.
redirect the user to the client admin via a login page. The paramters would be the token and username. The login function would then go to that user in the database and verify the token.
On successful authorization of token the CI client app would start a session and let the user in.
This seems like a very long winded method. Ideally there would be a way to start a session for one CI app from another?
Any ideas?
Thanks.
Once you've verified admin or client, I would use the CodeIgniter session class with the ci_sessions table in your database.
http://codeigniter.com/user_guide/libraries/sessions.html
Then to distinguish users from client or employee add a variable to the session.
$this->session->set_userdata('user_type', 'client');
Then just use that if ever you need it.
I would go about making 2 applications under HMVC (Hierarchical-Model-View-Controller) framework.
HMVC CodeIgniter Tutorial
Then you can go about using same sessions under multiple applications, as well as use the same models for user management, etc..
HMVC helps you modularize your applications, thus if you want to add more applications in the future, you can easily do that, passing over same sessions and such.
I answered your question in a bigger scope, one central login with 2 apps, best should be done with HMVC.
:)
Might wanna check out BackEndPro for CodeIgniter, could save you a lot of time.
Includes:
User Authentication with registration & account activation
User Permissions by using ACL (Access Control Lists)
Admin GUI backend for editing Site-wide Preferences
Built on Matchbox (for Modular development)
Asset Library (optimize, cache, and load JS & CSS)
ReCAPTCHA
Status messages (info/success/warning/error messages for the user)

Categories