Registering users in Laravel as Admin - laravel

My current project is a school management system, and I'm using Laravel 5.6 (it's my first Laravel project). I've been trying to register a user from a small form I have inside the Administrator area of my application.
I've set up the routes for the Admin area (view names are not in English, sorry for that):
// Admin
Route::middleware(['auth'])->group(function () {
Route::view('/admin', 'profiles.admin.admin_gerencia_cadastro');
Route::view('/admin/gerencia/cadastro', 'profiles.admin.admin_gerencia_cadastro');
Route::post('/admin/gerencia/cadastro', 'RegController#store');
Route::view('/admin/gerencia/relatorios', 'profiles.admin.admin_gerencia_relatorios');
Route::view('/admin/ped/', 'profiles.admin.admin_ped');
});
The post route (third from the top) was supposed to handle registration of users and leads to RegController and the following method:
public function store()
{
$this->validate(request(), [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
$user = User::create(request(['name', 'email', 'password']));
return redirect()->to('/admin/gerencia/cadastro');
}
It should store the new user data and redirect the Admin back to /admin/gerencia/cadastro. However, when the form is submitted data is not stored on the database and I'm redirected to the homepage instead. I've tried different things, consulted the documentation, but no success so far.
Any help will be much appreciated.
Edit:
Came here to post the form, as requested below, but I found my own mistake - a rookie one: the form action was wrong. Sorry guys, I'll close the question :)

Is your request reaching in store() method?
try to write
print_r($_REQUEST);exit;
on first line of method. If it's not reaching there, then put below route before all other routes of your route group:
Route::post('/admin/gerencia/cadastro', 'RegController#store');
check out this link for better understanding of routing in laravel.

Related

Why InitializeTenancyByDomain is not applicable for the login process?

This is for Laravel 8.x with Jetstream/Livewire scaffold having Stancl/Tenancy. The initialization of tenant models or session settings not working right. Either I did not do it right or inbuilt problem.
The entire package was built as per instructions of Stencl/tenancy v3.x. I can see the dd(\App\User::all()) as per code outlined below
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function (){
Route::get('/', function () {
dd(\App\User::all()); //can see all users models in tenants table
return view('welcomeTenant');
});
Route::get('/home', [
'middleware' => ['auth'],
'uses' => '\App\Http\Controllers\HomeController#index'
])->name('home');
});
This meant InitializeTenancyByDomain right to me.
When a login form is requested from tenant's domain eg. from rtbs.example.in, the encrypted session/cookie info is not stored in sessions table of tenant i.e. rtbs.sessions. When a login form is posted, it is looking for users in central domain (example.in) where users table is not present, hence the central.users table not exist error. As a result I get 419 error. I had disabled the csrf token verification temporarily to identify this problem.
This is the issue. Why the InitializeTenancyByDomain is not applicable for the login process? Could there be a fundamental setting wrong with me? Interestingly, the dd(\App\User::all()) if present anywhere else i.e. as show below
Route::middleware([
'web',
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class,
])->group(function (){
dd(\App\User::all()); //central-domain.users does not exist error
Route::get('/', function () {
return view('welcomeTenant');
});
Route::get('/home', [
'middleware' => ['auth'],
'uses' => '\App\Http\Controllers\HomeController#index'
])->name('home');
});
The same sql exception i.e. central-domain.users table does not exist is thrown. Only when present inside the Route::get('/'... i can see the correct models.
I had this problem with Laravel Fortify, which provides the backend to JetStream. It only became a problem when I changed the session driver to database from file - though this will be necessary for my deployment anyway.
The issue is that Fortify makes extensive use of dependency injection inside the constructor methods of their controllers. As described in the documentation for Tenancy, because of the lifecycle of a Laravel request the tenancy will not be available when these constructors run. This means they will default to the central connection and cause failure to login.
Because we can't change the way Fortify uses constructors, the solution is to change the middleware to be global and add a check for central domains into the initialization middleware:
Copy Stancl\Tenancy\Middleware\InitializeTenancyByDomain to App\Middleware\InitializeTenancyByDomain changing:
public function handle($request, Closure $next)
{
//Skip for central domains
if(in_array($request->getHost(), config('tenancy.central_domains'), true)){
return $next($request);
}
return $this->initializeTenancy(
$request, $next, $request->getHost()
);
}
App/Http/Kernel
use App\Http\Middleware\InitializeTenancyByDomain;
protected $middleware = [
// ...
InitializeTenancyByDomain::class,
];
Config/fortify
use Stancl\Tenancy\Middleware\PreventAccessFromCentralDomains;
'middleware' => [
'web',
PreventAccessFromCentralDomains::class,
],
Routes/tenant
Route::middleware([
'web',
PreventAccessFromCentralDomains::class,
])->group(function () {
//Your Routes
}
With this solution Fortify and Stancl Tenancy are now working well together with well separated databases, sesssions and logins.
I got it to work with Rory's answer. However, you need to set the correct namespace in App\Http\Middleware\InitializeTenancyByDomain.php:
namespace App\Http\Middleware; // << use this instead of Stancl\Tenancy\Middleware
// [..]
use Stancl\Tenancy\Middleware\IdentificationMiddleware; // <<
class InitializeTenancyByDomain extends IdentificationMiddleware
That package is very helpful, but it requires a lot of work to get all the pieces lined up and maintained. You've got the right middleware, including 'web' and the two tenancy bits, which will start the session and allow checks for CSRF.
I've had similar problems before. The biggest cause for me was that it was not finding the right 'central' path, and thus not initializing tenancy correctly.
Make sure your tenancy.php config file is showing the right central domain. Something like:
'central_domains' => [
'example.in' // No http:// here
],
Route's like next can issue bugs with database session store
Route::view('some')
You could use a feature called Universal Routes check the documentation here

Where to apply custom middleware for authentication Laravel 5.2

In my project two type of users, Admin and Normal User. They are identified by the field isAdmin in users table. User can edit their profile by using the function below
public function userEditprofile(){
$user_detail = userDetail::find(Auth::user()->id);
$user_detail->address = Input::get('address');
.......
$user_detail->save()
return Redirect::route('showUserProfile');
}
and route is
Route::group(['middleware' => 'my_profile'], function() {
Route::get('/editprofile', array('uses' => 'UserController#userEditprofile', 'as' => 'userEditprofile'));
});
Admin can also edit any users profile by using
public function adminEditUserprofile($user_id){
$user_detail = userDetail::find($user_id);
$user_detail->address = Input::get('address');
.......
$user_detail->save()
return Redirect::route('showUserProfile', $user_id);
}
In both cases action is same but in first method there is no parameter is required. But in the case of admin , a parameter is required. Can I optimize the code by using any other way? I am a self learned programmer. I am not much aware of efficient programming methods.Can anyone reply?
I believe you should rather implement role based authorization. A good example has already been implemented by rappasoft/laravel-5-boilerplate
You should actually prefer this boilerplate as it includes a lot that is necessary for most of business applications.

Laravel 5 and Socialite - New Redirect After Login

Another newb question here, but hopefully someone can shed some light:
I am using Socialite with Laravel 5, and I want to be able to redirect the user to a page on the site after they have logged in. The problem is that using
return redirect('any-path-I-put-here');
simply redirects back to 'social-site/login?code=afkjadfkjdslkfjdlkfj...' (where 'social-site' is whatever site is being used i.e. facebook, twitter, google, etc.)
So, what appears to me to be happening is that the redirect() function in the Socialite/Contracts/Provider interface is overriding any redirect that I attempt after the fact.
Just for clarification, my routes are set up properly. I have tried every version of 'redirect' you can imagine ('to', 'back', 'intended', Redirect::, etc.), and the method is being called from my Auth Controller (though I have tried it elsewhere as well).
The question is, how do I override that redirect() once I am done storing and logging in the user with socialite? Any help is appreciated! Thank you in advance.
The code that contains the redirect in question is:
public function socialRedirect( $route, $status, $greeting, $user )
{
$this->auth->login( $user, true );
if( $status == 'new_user' ) {
// This is a new member. Make sure they see the welcome modal on redirect
\Session::flash( 'new_registration', true );
return redirect()->to( $route );// This is just the most recent attempt. It originated with return redirect($route);, and has been attempted every other way you can imagine as well (as mentioned above). Hardcoding (i.e., 'home') returns the exact same result. The socialite redirect always overrides anything that is put here.
}
else {
return redirect()->to( $route )->with( [ 'greeting' => $greeting ] );
}
}
... The SocialAuth class that runs before this, however, is about 500 lines long, as it has to determine if the user exists, register new users if necessary, show forms for different scenarios, etc. Meanwhile, here is the function that sends the information through from the Social Auth class:
private function socialLogin( $socialUser, $goto, $provider, $status, $controller )
{
if( is_null( $goto ) ) {
$goto = 'backlot/' . $socialUser->profile->custom_url;
}
if( $status == 'new_user' ) {
return $controller->socialRedirect($goto, $status, null, $socialUser);
}
else {
// This is an existing member. Show them the welcome back status message.
$message = 'You have successfully logged in with your ' .
ucfirst( $provider ) . ' credentials.';
$greeting =
flash()->success( 'Welcome back, ' . $socialUser->username . '. ' . $message );
return $controller->socialRedirect($goto, $status, $greeting, $socialUser);
}
}
I managed to workaround this problem, but I am unsure if this is the best way to fix it. Similar to what is stated in question, I got authenticated callback from the social media, but I was unable to redirect current response to another url.
Based on the callback request params, I was able to create and authenticate the user within my Laravel app. It worked good so far but the problems occured after this step when I tried to do a return redirect()->route('dashboard');. I tried all the flavours of redirect() helper and Redirect facade but nothing helped.
The blank page just stared at my face for over 2 days, before I checked this question. The behaviour was very similar. I got redirect from social-media to my app but could not further redirect in the same response cycle.
At this moment (when the callback was recieved by the app and user was authenticated), if I refreshed the page manually (F5), I got redirected to the intended page. My interpretation is similar to what's stated in this question earlier. The redirect from social-media callback was dominating the redirects I was triggering in my controller (May be redirect within Laravel app got suppressed because the redirect from social-media was still not complete). It's just my interpretation. Experts can throw more light if they think otherwise or have a better explaination.
To fix this I issued a raw http redirect using header("Location /dashboard"); and applied auth middleware to this route. This way I could mock the refresh functionality ,redirect to dashboard (or intended url) and check for authentication in my DashboardController.
Once again, this is not a perfect solution and I am investigating the actual root of the problem, but this might help you to move ahead if you are facing similar problem.
I believe you are overthinking this. Using Socialite is pretty straight forward:
Set up config/services.php. For facebook I have this:
'facebook' => [
'client_id' => 'your_fb_id',
'client_secret' => 'your_fb_secret',
'redirect' => '>ABSOLUTE< url to redirect after login', //like: 'http://stuff'
],
Then set up two routes, one for login and one for callback (after login).
In the login controller method:
return \Socialize::with('facebook')->redirect();
Then in the callback function
$fb_user = \Socialize::with('facebook')->user();
// check if user exists, create it and whatnot
//dd($fb_user);
return redirect()->route('some.route');
It should be pretty much similar for all other providers.
We are using the Socialite login in our UserController as a trait. We simply overrode the AuthenticatesSocialiteLogin::loginSuccess() in our controller.
use Broco\SocialiteLogin\Auth\AuthenticatesSocialiteLogin;
class UserController extends BaseController
{
use AuthenticatesSocialiteLogin;
public function loginSuccess($user)
{
return redirect()->intended(url('/#login-success'));
}
....

How to keep session data using Codeigniter and Tank Auth

I'm using Codeigniter and Tank Auth for a e-commerce website. I'm finding that if a customer puts items into the cart (using the Codeigniter built in cart class) and then registers on the site the session is lost along with their cart (I'm presuming it generates a new session for some reason instead of keeping the same session).
Has anyone come across this problem before? and is there a simply solution that I have overlooked.
Thanks
As far as the most recent code looks like, the only place the hole session is deleted is in the logout() function, Tank_auth.php Line 118:
https://github.com/ilkon/Tank-Auth/blob/master/application/libraries/Tank_auth.php#L118
The example usage of Tank Auth uses logout() in activate() and reset_email() - check your code for those methods. You could also change the Tank Auth logout function to something like this:
function logout($keep_session = false)
{
$this->delete_autologin();
// See http://codeigniter.com/forums/viewreply/662369/ as the reason for the next line
$this->ci->session->set_userdata(array('user_id' => '', 'username' => '', 'status' => ''));
if(!$keep_session)
$this->ci->session->sess_destroy();
}
... and the use it like this: $this->tankauth->logout(true);

Magento - Customer Not Logged in After Redirect From External Page

I'm having a lot of trouble getting a customer to stay logged in after I have created a new account. I'm creating them an account and adding products to a cart from an external site, and then sending them to Magento store. What I want to have happen is:
A customer goes to a signup page and enters relevant information.
They go to a new page where they can choose to add free samples to their cart.
After picking samples. their account is created and they are redirected to the Magento store with the samples in their cart.
The problem I'm having is between steps 2 and 3. I create an account using the Magento's SOAP API with the following:
$customerInfo = array('firstname' => $custFirstname, 'lastname' => $custLastname, 'email' => $email, 'password_hash' => md5( $new_password ), 'store_id' => 34, 'website_id' => 25,'group_id' => 9);
// Call API method customer.create
$newCustomerId = $client->call( $session, 'customer.create', array( $customerInfo ) );
I then return their customer ID, which I pass to another function which actually logs them in and adds products to their cart:
public static function _addSamplesToCart($customer_id, $sample_one, $sample_two, $sample_three){
Mage::getSingleton("core/session", array("name" => "frontend"));
$customerSession = Mage::getSingleton('customer/session', array("name" => "frontend"));
$customerSession->init("customer_bn_us");
$customerSession->loginById($customer_id);
$cart = Mage::getSingleton('checkout/cart');
$cart->addProductsByIds($idArray);
$cart->save();
$cart->getCheckoutSession()->setCartWasUpdated(true);
}
These functions are actually called from AJAX post requests, so when I get a successful return value from _addSamplesToCart, I do a simple javascript redirect (window.location ="http://www.myhostname.net/welcome") and it correctly takes me there, but I'm not logged in.
I've been looking around all afternoon and trying a few different things and nothing has worked. I've also tried doing a hidden form submit to /customer/account/loginPost and it still doesn't work. I have verified that it's correctly creating an account in Magento. My only hunch is that I'm doing this with a mix of AJAX and PHP so somehow the cookies or sessions are getting mixed up?
If you are trying to login from an hostname different from the one used by the Magento store, it cannot work. You can verify this by checking if a frontend cookie is created after the AJAX call.
I suggest you to create a new controller in Magento that receives the id of the customer just created and executes the code you wrote in your function:
www.myhostname.net/autologin/myaction/13 (where 13 is the id of the customer just created).
Obviously you should add something else to avoid security issues.

Resources