Laravel - Check if user is authenticated on another server - laravel

Let say I have a laravel site on a host and another host just for storing some specific files. In second host I want to check if user is authenticated on laravel site and then I gave him/her access to the file. How can I do this?

You could pretty much just use normal PHP code for that, without having to touch the Laravel framework on your other server.
For example, create your own custom cookie or session variable that contains a token from authentication. Make the logic something like $authToken = md5($user->username) . "." . md5($user->password);, then just add it to a cookie or the $_SESSION[] variable.
From here, create a small backend on the other server that you use for storage, and do something like this.
<?php
/////////////
/**
* Here there should be database connection logic.
*/
/////////////
$posts = (object) $_POST;
if ($_SERVER['REQUEST_METHOD'] == "POST")
{
$postArray = [
'authToken',
'user'
];
foreach($postArray as $post)
{
if (!isset($_POST[$post]))
{
return false;
}
}
$query = htmlspecialchars("SELECT * FROM users WHERE id=" . $posts->user);
$result = mysqli_query($connection, $query);
$row = mysqli_fetch_all($result);
$db_stack = md5($row['username']) . "." . md5($row['password']);
if ($posts->authToken != $db_stack)
{
return false;
}
// Return the requested file here.
}

If (Auth::check()) $file = file_get_contents($urlToFile);

Related

Laravel login without register

Is it possible to login a user in Laravel 7 without having the user on the database? I have a group of users, which I don't want them on my database, because they use an external API to do the login and I can get their details from that API (via XML).
There are 3 types of users:
AR division users. Normal registered users.
Non-AR division users, but $user->gca = 1. Registered users too.
Non-AR division and Non-GCA users. Non-registered users.
All of them use an external API for the login. However, I only register the first 2 ones on my database for organisational purposes.
My intention is to use Laravel login using the 3rd type user details from the API without touching my database.
My code at LoginController.php
$user_array = json_decode(file_get_contents($this->api_url . '?type=json&token=' . $request->cookie($this->cookie_name)));
if ($user_array->result)
{
$u = NULL;
if ($user = User::find($user_array->vid)) $u = $user;
else if($user_array->division == 'AR' || !is_null(Gca::find($user_array->vid)))
{
$u = new User();
if(! is_null(Gca::find($user_array->vid))) $u->gca = 1;
$u->name = $user_array->firstname;
$u->vid = $user_array->vid;
$vid = $u->vid;
$u->save();
return view('register', compact('vid'));
}
else
{
$user = new User();
$user->division = $user_array->division;
$user->vid = $user_array->vid;
$user->name = $user_array->firstname;
$user->surname = $user_array->lastname;
Auth::login($user); //This doesn't seem to work.
return redirect('/');
}
}
Thanks.

ADLDAP openLDAP authentication - Session not stored - returning to login page

My environment is a laravel 5.8 with adldap2 in version 6.0.8 web app and an openLDAP directory.
After hours, I finally could authenticate my user against the openLDAP directory and also the database import into the users table works:
Id name username password remember_token created_at updated_at
King king $2y$10$YF9q7cYqjYnkl.We4Evwv.u/a2sddrfBA3pohgpS2vR... j4AOUHSlkHE3IQW7bsgF7pOIY8EAss6iukfnKhwi2lqXR0eTjE... NULL NULL
When I check the variable user in the function: attemptLogin -> $this->guard()->login($user, true); it is from the DB and seems to be fine. But still after I log in, I also get the message "Redirecting to http://localhost/home.", it returns to the login page and is still not logged in.
For LDAP authentication I followed mostly this example: https://jotaelesalinas.github.io/laravel-simple-ldap-auth/ even if it is a bit obsolete.
My attemptLogin function looks like this:
protected function attemptLogin(Request $request)
{
$username = Adldap::search()->users()->select('mail','uid','displayName')->findBy('cn', request()->get('username'));
$result = 1;
if($username){
if(Adldap::auth()->attempt($username->getdistinguishedName(), request()->get('password'))){
echo("success");
// Check group
$group = Adldap::search()->groups()->findOrFail('cio');
foreach ($group->getMemberNames() as $name) {
if($name === $username->getAccountName()){
echo("The user is a member of the group.");
$result = 0;
}
}
if ($result != 0){
$result = 2;
}
} else {
echo("Password wrong");
$result = 1;
}
} else {
echo(request()->get('username') . " not found");
$result = 1;
}
if($result == 0) {
// the user exists in the LDAP server, with the provided password
echo("Everything ok");
$user = \App\User::where($this->username(), $username->getAccountName())->first();
if (!$user) {
// the user doesn't exist in the local database, so we have to create one
$user = new \App\User();
$user->username = $username;
$user->password = '';
// you can skip this if there are no extra attributes to read from the LDAP server
// or you can move it below this if(!$user) block if you want to keep the user always
// in sync with the LDAP server
//dd($username->getDisplayName());
$sync_attrs = $this->retrieveSyncAttributes($username->getAccountName());
//dd($sync_attrs);
foreach ($sync_attrs as $field => $value) {
$user->$field = $value !== null ? $value : '';
}
}
$this->guard()->login($user, true);
return 0;
}
// the user doesn't exist in the LDAP server or the password is wrong
// log error
return $result;
}
Web.php
Route::get('login', 'Auth\LoginController#showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController#login');
Route::post('logout', 'Auth\LoginController#logout')->name('logout');
Route::get('/home', 'HomeController#index')->name('home');
Has anyone an idea what I am missing? Or if you need more information, please tell me. It seems like the session is not stored.
Thanks in advance
Stephan
A small update after playing around some more hours. It seems like that Auth is after the successful login null. So tried different approaches I could find on the internet like changing the web.php routes or adding the protected $user variable to the LoginController.php but of course without any success.
I figured out that when I change the middleware from auth to web, I will get a session but the Auth::User() is still empty
Route::group(['middleware' => 'auth'], function () {
Route::get('/home', 'HomeController#index')->name('home');
});
After spending more and more hours, I finally found the solution in this thread: Laravel Auth:attempt() will not persist login
My issue was that I was using "echo's".
It cost me probably some days of my life

Can I give my user a choice to choose his own subdomain in Laravel project?

I have implemented multi-tenancy in a project with unique subdomains & separate dbs. Now, my client said that we will provide subdomain of customer’s choice. In this way, duplication is obvious. The flow is like this:
If two users have this one domain (user1 => http://user.abc.com & user2 => http://user.abc.com ), then how can I determine who is who? The main problem is, I am going to register the user myself, there is no registration process for the customer, so, customer will provide his domain to us manually for example: he likes to have his domain “user” and if I would have “user” already in my database, how can I provide the same hostname to my another customer. Won’t it seems strange that we are calling our customer back and telling them that we have already this hostname please give us another name of your choice. Yes, all this makes sense when we would have been giving the registration process to our customer and there he can enter hostname of his own choice like we enter our email addresses on gmail, hotmail and etc. Please tell me if I am going in wrong direction.
Here is my code:
routes/web.php
Route::group(['middleware' => 'subdomain'], function () {
Route::get('/sales', 'HomeController#index');
Route::get('/sales/register', 'HomeController#register');
});
Middleware/SubDomainAccess.php
public function handle($request, Closure $next)
{
$server = explode('.', $request->server('HTTP_HOST'));
$subdomain = $server[0];
$config = array();
if($subdomain == "myapp"){
$defaultSite = SuperAdminModel::where('db_name', 'main_db)->first();
$config['id'] = $defaultSite["admin_id"];
$config['site_url'] = $defaultSite["site_url"];
$config['host'] = "localhost";
$config['db_name'] = "main_db";
$config['user'] = "my_user";
$config['password'] = "mypassword";
$request->attributes->add(['myAttribute' => "SUPER ADMIN"]);
}
else{
$site = TenantModel::where('tenant_hostname', $subdomain)->first();
if(!is_null($site)){
$config['id'] = $site["id"];
$config['tenant_domain'] = $site["tenant_domain"];
$config['tenant_hostname'] = $site["tenant_hostname"];
$config['db_name'] = "mysite_".$site["id"]."_".$site["tenant_hostname"]."_db";
$config['user'] = "my_user";
$config['password'] = "mypassword";
$config['host'] = "localhost";
$request->attributes->add(['myAttribute' => $site['tenant_company_name']]);
}else{
return abort(404);
}
}
\Config::set('database.connections.mysql.host', $config['host'] );
\Config::set('database.connections.mysql.database', $config['db_name'] );
\Config::set('database.connections.mysql.username', $config['user']);
\Config::set('database.connections.mysql.password', $config['password']);
\DB::reconnect();
return $next($request);
}
If more details are required to understand the code, I will provide it.
Thank you

Yii2. Authorised users list

I've used standard yii2 functions for authorization. User sessions are stored in database.
How can I get the list of all authorized users in Yii2?
Use this code:
$sessions = (new Query())->select('*')->from('session')->where('expire > :now', [
':now' => time()
])->all();
foreach($sessions as $session) {
$sessionData = Yii::$app->session->readSession($session['id']);
$sessionUnserializedData = $this->unserialize_session($sessionData);
$userId = $sessionUnserializedData['__id'];
echo $userId;
}
unserialize_session method get from #phred gist.

Magento User Sub-Accounts for Impersonation

I have a requirement for a Magento project that accounts are hierarchical. That is one account can "own" multiple other accounts. If one account owns another account it is allowed to impersonate that account: create orders, view account information, and view previous orders.
I'm not sure where to begin. If you have any thoughts, could you please point me in the right direction?
One solution would be to set up a Multiple Select attribute and populate it with the user ids of the users allowed to impersonate. You could then create either a separate php file that runs magento and logs in the user based on who they select, or integrate it into the cms.
Here is my custom 'login' code that lets my sso users from my Microsoft Database login to magento.
You call this function and pass it a 'user' you want to login as. Seems to work pretty well, however you will need to modify it to your needs. Don't expect it to work out of the box!
FYI: if you don't pass in all the junk that magento needs about the dispatchevents() then the user will not login properly. I had to reverse engineer this whole dern thing, so don't expect to see it anywhere else besides here and bits and pieces of magento core :)
$userId = 5;
$user = Mage::getModel('customer/customer')->load($userId)->setWebsiteId(1);
$this->LoginToMagento($user, null);
function LoginToMagento($user, $noAddress) {
// Must include this file in order to use the object
include ('/var/www/app/code/core/Mage/Customer/controllers/AccountController.php');
// Configure Magento to think its using the frontend
Mage::getSingleton("core/session", array("name" => "frontend"));
Mage::getConfig()->init();
Mage::getConfig()->loadEventObservers('frontend');
Mage::app()->addEventArea('frontend');
Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_FRONTEND);
// Grab the request and modify it with my emulated controller's information
$request = Mage::app()->getRequest();
$request->setRouteName('customer');
$request->setControllerModule('Mage_Customer');
$request->setRoutingInfo('');
$request->setModuleName('customer');
$request->setControllerName('account');
$request->setModuleKey('module');
$request->setControllerKey('account');
$request->setActionName('loginPost');
$request->setActionKey('action');
// Grab the response
$response = Mage::app()->getResponse();
// Feed the request and response into a new accountcontroller object
$accountControl = new Mage_Customer_AccountController($request, $response);
// Dispatch events related to the controller actions for predispatch
Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $accountControl));
Mage::dispatchEvent('controller_action_predispatch_customer', array('controller_action' => $accountControl));
Mage::dispatchEvent('controller_action_predispatch_customer_account_loginPost', array('controller_action' => $accountControl));
// Grab an instance of the customer session model
$session = Mage::getSingleton('customer/session');
try{
// Attempt to login the user
$session->setCustomerAsLoggedIn($user);
$session->renewSession();
} catch (Mage_Core_Exception $e) {
// Lets hope to never get here
$message = $e->getMessage();
error_log($message);
Mage::getSingleton('core/session')->addError($message);
}
// Perform the postdispatch events for 'after emulation of the controller'
Mage::dispatchEvent('controller_action_postdispatch_customer_account_loginPost', array('controller_action'=>$accountControl));
Mage::dispatchEvent('controller_action_postdispatch_customer', array('controller_action'=>$accountControl));
Mage::dispatchEvent('controller_action_postdispatch', array('controller_action'=>$accountControl));
$customer = Mage::getModel('customer/customer')
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('entity_id', array('eq' => $user->getId()))
->getFirstItem();
try
{
// Prepare a collection of required values that the customer *should* have been set from netforum
$collection = Mage::getModel('eav/entity_attribute')->getCollection();
$collection->addFieldToFilter('entity_type_id', Mage::getModel('eav/entity')->setType('customer')->getTypeId());
// The var representing if validation has failed
$failedReq = false;
// Loop through each user defined required attribute and if we find one
// on the customer that is not set, forward the user to their account config page
foreach ($collection as $attribute)
{
if ($attribute['is_required'] && $attribute['is_user_defined'])
{
$attrCode = $attribute['attribute_code'];
if (!isset($customer[$attrCode]))
{
$failedReq = true;
}
}
}
// Try to determine where we logged in from (URL)
Mage::getSingleton("core/session", array("name" => "frontend"));
$session = Mage::getSingleton("customer/session");
$outputMessage = $session->getData('before_auth_url');
// Proceeed differently based on the existence of addresses
if ($noAddress == true)
{
if ($failedReq)
{
// Customer failed login. To be expected if they are signing in with SSO and never have before
$redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/edit/';
Mage::getSingleton('core/session')->addError('<b>Please fill in the required fields marked with * and click "Save"</b>');
header("Location: $redirect_to");
}
else
{
// Customer checks out ok, but has no addresses. Send them to the address setup screen
Mage::getSingleton('core/session')->addError('<b>Please fill in your address and phone number, then click "Save"</b>');
$redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/address/edit/';
header("Location: $redirect_to");
}
}
else
{
// Customer has addresses being passed from SSO
$defaultBillingId = $customer->getDefaultBillingAddress()->getId();
$hasPhoneNumber = false;
foreach ($customer->getAddresses() as $address)
{
$addrs = Mage::getModel('customer/address')->load($address->getId());
$magePhone = $addrs->getTelephone();
if ($magePhone)
{
$hasPhoneNumber = true;
}
}
if ($failedReq)
{
// Customer failed login. To be expected if they are signing in with SSO and never have before
$redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/edit/';
Mage::getSingleton('core/session')->addError('<b>Please fill in the required fields marked with * and click "Save"</b>');
header("Location: $redirect_to");
}
else
{
// Customer is has default values filled out
if (!$hasPhoneNumber)
{
// Phone number is missing for an address so redirect there and force em to enter it.
Mage::getSingleton('core/session')->addError('<b>Please fill in the required fields marked with * and click "Save Address"</b>');
$redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/address/edit/id/' . $defaultBillingId;
header("Location: $redirect_to");
}
else
{
// Everything is ok, so just try to send them back to where they came from, or the account screen
if ($outputMessage)
{
$redirect_to = $outputMessage;
}
else
{
$redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/';
}
header("Location: $redirect_to");
}
}
}
}
catch (Exception $e)
{
if ($outputMessage)
{
$redirect_to = $outputMessage;
}
else
{
$redirect_to = 'https://' . $_SERVER['HTTP_HOST'] . '/customer/account/';
}
header("Location: $redirect_to");
}
}
I know I am late but
http://amasty.com/sales-reps-and-dealers.html
This extension can be helpful to achieve what you are looking for. It will allow to create hierarchical accounts and assign the sales rep/sub admins to the orders and provide the access levels.
Hope this helps.

Resources