In my app I have two types of users - admin and teacher. In my AuthController I have this :
public function getLogin() {
return view('auth.login');
}
public function postLogin(\Illuminate\Http\Request $request) {
if(Auth::attempt([
'username' => $request->input('username'),
'password' => $request->input('password'),
'type' => 'admin'
])) {
return redirect ('admin');
}
if(Auth::attempt([
'username' => $request->input('username'),
'password' => $request->input('password'),
'type' => 'teacher'
])) {
return redirect ('educator/account');
}
return redirect('login')->with('message', [
'type' => 'danger',
'message' => 'Грешно потребителско име или парола!'
]);
}
public function getLogout() {
Auth::logout();
return redirect('login');
}
But when I'm logged in as a user with type teacher if i go to http://localhost/school_system/public/admin I automatically go to the admin panel without asking for username and password. I want if I want to go to the admin panel from the teacher account this to happen with asking for username and password, how can I make this?
My routes:
Route::group(['middleware' => ['auth']
], function () {
Route::group([
'prefix' => 'admin',
'namespace' => 'Admin'
], function () {
Route::controller('student', 'StudentsController');
Route::controller('profile', 'ProfilesController');
Route::controller('class', 'ClassesController');
Route::controller('subjects', 'SubjectsController');
Route::controller('teacher', 'TeachersController');
Route::controller('marktype', 'MarkTypeController');
Route::controller('rules', 'RuleController');
Route::get('{slug?}', 'PageController#getView');
});
});
Route::group(['middleware' => ['auth']
], function () {
Route::group([
'prefix' => 'educator',
'namespace' => 'Educator'
], function () {
Route::controller('account', 'AccountController');
Route::get('{slug?}', 'EducatorController#getView');
});
});
Thanks ^^
You can create an "adminmiddleware" : php artisan make:middleware AdminMiddleware
Example of code you can use
if ($request->user()->type != 'admin')
{
return redirect('home');
}
and in the route:
Route::group(['middleware' => ['admin']...
Finished ;)
Related
When someone signs up they can register as a profile or business in a drop select. From my code below, how do I create middleware so the profile user can't access the business dashboard and the business user can't access the profile dashboard? How do I protect those pages?
2014_10_12_000000_create_users_table.php
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('account_type');
$table->string('first_name');
$table->string('last_name');
$table->string('username')->unique();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('phone');
$table->string('address', 50);
$table->string('city', 25);
$table->char('state', 2);
$table->char('zip', 10);
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
RegisterController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class RegisterController extends Controller
{
public function index()
{
return view('auth.register');
}
public function store(Request $request)
{
$this->validate($request, [
'account_type' => 'required|not_in:0',
'first_name' => 'required|max:255',
'last_name' => 'required|max:255',
'username' => 'required|max:15|unique:users',
'email' => 'required|email|unique:users',
'phone' => 'required|max:255|digits:10',
'address' => 'required|max:255',
'city' => 'required|max:20',
'state' => 'required|not_in:0',
'zip' => 'required|regex:/\b\d{5}\b/',
'password' => 'required|string|confirmed|min:8',
]);
User::create([
'account_type' => $request->account_type,
'first_name' => $request->first_name,
'last_name' => $request->last_name,
'username' => $request->username,
'email' => $request->email,
'phone' => $request->phone,
'address' => $request->address,
'city' => $request->city,
'state' => $request->state,
'zip' => $request->zip,
'password' => Hash::make($request->password),
]);
Auth::attempt([
'email' => $request->email,
'password' => $request->password,
]);
// Redirect to dashboards based on registers account type
if(Auth::user()->account_type == 'profile'){
return redirect()->route('dashboard_profile');
} else {
return redirect()->route('dashboard_business');
}
}
}
BusinessDashboardController.php
class BusinessDashboardController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('auth.dashboard_business');
}
}
ProfileDashboardController.php
class ProfileDashboardController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('auth.dashboard_profile');
}
}
I want to learn to do this without using packages.
In addition to the solution given by #nagidi, you can update the middleware handle condition to check either account_type is profile or business.
public function handle($request, Closure $next, $type)
{
if (Auth::user() && Auth::user()->account_type == $type) {
return $next($request);
}
abort(403, 'Unauthorized action.');
}
Route::get('/business-profile', ['middleware' => 'accType:business', function () {
//
}]);
Route::get('/profile', ['middleware' => 'accType:profile', function () {
//
}]);
1- run :
php artisan make:middleware AccountType
2- Add it to the routeMiddleware array in your kernel file by opening app/Http/Kernel.php:
'accType' => \App\Http\Middleware\AccountType::class,
3- Edit AccountType file:
public function handle($request, Closure $next)
{
// If user account type is profile allow to next or else block the request
if (Auth::user() && Auth::user()->account_type == 'profile') {
return $next($request);
}else{
abort(403, 'Unauthorized action.');
}
}
4- Apply the middleware to your route:
Route::get('/profile', ['middleware' => 'accType', function () {
//
}]);
If your want to have a multi authenticate system, whit different logics, its better to implement multiple guard and define them in your desire models :
[...]
'guards' => [
[...]
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'writer' => [
'driver' => 'session',
'provider' => 'writers',
],
],
[...]
[...]
'providers' => [
[...]
'admins' => [
'driver' => 'eloquent',
'model' => App\BusinessDashboard::class,
],
'writers' => [
'driver' => 'eloquent',
'model' => App\ProfileDashboard::class,
],
],
[...]
you can find a complete guide article in bellow code :
enter link description here
How to create your own middleware for multi User Role in Laravel
Let assumed your roles array could be ["admin","student","staff"];
Create a middleware role checking for the role "admin". Repeat steps 1-4 for each role.
I found this much easier for myself, others may have their own approaches
Step 1
Run artisan command
php artisan make:middleware isAdmin
Step 2
App/Http/Middlewere/isAdmin.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class isAdmin
{
public function handle(Request $request, Closure $next,$is_admin)
{
$role=Auth::user()->role;
//Get the role list
$role_array=explode(",",$role);
if (in_array($is_admin, $role_array)) {
return $next($request);
}
//if not allowed redirect to home page with message
$message="Unauthorized action.";
//return response($message, 401);//if you have friendly 401 page
//otherwise I think is a best to return to home page
$request->session()->flash('error', $message);
return redirect()->route('home');
}
}
Step 3
App/Http/Kernel.php
protected $routeMiddleware = [
'isAdmin' => \App\Http\Middleware\isAdmin::class,
];
Step 4
Now in your route controller add this line to only allow the user that has an admin role
public function __construct()
{
//ONLY ADMIN CAN ACCESS THIS ROUTE
$this->middleware('isAdmin:admin');
//$this->middleware('isStudent:student');
//$this->middleware('isStaff:staff');
}
I'm having problem redirecting my admin page to a Route::resource(); so that I could display my CRUD from the BookController
What am I doing wrong?
This is my AdminLoginController:
public function __construct(){
$this->middleware('guest:admin');
}
public function showLoginForm(){
return view('auth.admin-login');
}
public function login(Request $request){
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if(Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password],$request->remember)){
return redirect()->intended(route('books.index'));
}
return redirect()->back()->withInput($request->only('email','remember'));
}
BookController
public function index()
{
$books = Book::orderBy('id','desc')->paginate(3);
return view('books.index')->withBooks($books);
}
web.php
Route::prefix('admin')->group(function(){
Route::get('/login','Auth\AdminLoginController#showLoginForm')>name('admin.login');
Route::post('/login','Auth\AdminLoginController#login')>name('admin.login.submit');
Route::get('/books/','BookController#index');
});
I think you should update your books route:
Route::get('/books/','BookController#index')->name('books.index');
OR
Route::group(['prefix' => 'admin'], function () {
Route::resource('/books','BookController#index');
});
and check your route name in php artisan route:list
update your code like:
if(Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password],$request->remember)){
return redirect()->intended(route('admin.books.index'));
}
Hope this work for you!
i want to make an auto login after successful registration and redirect to Edit Profile page.. I tried the following code but not working as i want
class RegisterController extends Controller
{
use RegistersUsers;
protected $redirectTo = '/edit_profile';
public function __construct()
{
$this->middleware('guest');
}
public function createUser(Request $request)
{
$this->validate($request , [
'firstName' => 'required',
'lastName' => 'required',
'displayName' => 'required',
'email' => 'required |email',
'password' =>'required ',
'gender' =>'required',
'day' =>'required|max:2',
'month' =>'required|max:2',
'year' =>'required|max:4',
]);
$email=$request->input('email');
$password=$request->input('paasword');
$dob=$request->input('day').'-'.$request->input('month').'-'.$request->input('year');
$request->request->add(['dob'=>$dob]);
$request->request->add(['password'=>bcrypt($request->input('password'))]);
$data = User::create($request->except(['_token', 'submit', 'day','month','year', 'confirm_password' ,'dayInWeek']));
Auth::login($data);
}
}
Routes
Route::get('/', 'PageController#login');
Route::get('/home', 'HomeController#index');
Route::group( ['middleware' => 'auth' ], function()
{
Route::get('main', 'PageController#main');
Route::get('browse', 'PageController#browse');
Route::get('pickngo', 'PageController#pickngo');
Route::get('edit_profile', 'PageController#profile');
}
Use Laravel loginUsingId($id) function by passing the user id.
$data = User::create($request->except(['_token', 'submit', 'day','month','year', 'confirm_password' ,'dayInWeek']));
Auth::loginUsingId($data->id);
just modify your auth login just like
if(Auth::login($data)) {
return redirect('/edit_profile');
}
else
{
return redirect()->back();
}
Scren from documentation.
You just need to add after login redirectTo property or method inside your LoginController.
P.S.it will work if you're using laravel's make:auth.
I'm facing problem in my Laravel 5.3 custom auth want to use my own functions or pages when I check Auth::check() it returns false.
Here is User controller:
namespace App\Http\Controllers;
use App\User;
use Illuminate\Support\Facades\Session;
use validatior;
use Auth;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function postSignUp(Request $request)
{
$validation = \Validator::make($request->all(), [
'email' => 'email|required|unique:users',
'password' => 'required|min:4'
]);
if ($validation->fails()) {
return redirect()->back()->withErrors($validation->errors());
} else {
$user = new User();
$user->email = $request->get("email");
$user->password = bcrypt($request->get['password']);
$user->save();
}
return redirect('signupPage');
}
public function postSignIn(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
if (Auth::attempt(['email' => $request['email'], 'password' => $request['password']])) {
return redirect('users/profile');
}
dd(Auth::check());
exit;
}
}
After sign in I want to redirect at profile page but my condition is not working. My routes are:
Route::group(['prefix' => 'users'], function(){
Route::group(['middleware' => 'guest'], function(){
Route::get('/signupPage','UserController#getSignUp');
Route::post('/register',array ('as'=>'signup', 'uses' =>'UserController#postSignUp', ));
Route::get('signInPage', array('as' => 'signInPage', 'uses' => 'UserController#getSignIn'));
Route::post('/postLogin', array('as' => 'postLogin', 'uses' => 'UserController#postSignIn'));
});
Route::group(['middleware' => 'auth'], function(){
Route::get('/profile', array('as' => 'profile', 'uses' => 'UserController#getProfile'));
Route::get('/logout', array('as'=>'logout', 'uses'=> 'UserController#logout'));
});
});
Here are some Modifications of your code
public function postSignUp(Request $request)
{
$email = $request->input('email');
$pass = $request->input('password');
$validation = \Validator::make($request->all(), [
'email' => 'email|required|unique:users',
'password' => 'required|min:4'
]);
if ($validation->fails()) {
return redirect()->back()->withErrors($validation->errors());
} else {
$pas = bcrypt($pass);
$user = new User();
$user->email = $email;
$user->password = $pas;
$user->save();
}
return redirect('users/signInPage');
}
Do use bcrypt while registering your User as this function is by default used by Auth Attempt function
public function postSignIn(Request $request)
{
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
$email= $request->input['email'];
$password= $request->input['password'];
if (Auth::attempt(['email'=>$email,'password'=>$password']))
{
return redirect('users/profile');
}
return redirect('users/signInPage')->withErrors(['failure' => 'The credentials you entered did not match our records. Try again!',]);
}
finally this will give you too many redirects error as you using default middlewares, because your logic is now differ from the default one that's why you have to write your custom middleware, for this run this command
php artisan make:middleware CutomAuth
this will create your custom middleware now write code in it by your logic and after registering in app/Http/Kernel.php as \n
'customauth' => \Illuminate\Auth\Middleware\CutomAuth::class, you are good to go
I tried to create a login, after I tried successfully identified,
return "Success Login";
but when I replace with
return Redirect::to('dashboard');
always returned to Login page
can you help me ? what's wrong with my code...
here is my code :
route.php
Route::get('login',array('as' => 'login', 'uses' => 'AuthController#getLogin'))->before('guest');
Route::post('login',array('uses' => 'AuthController#postLogin'))->before('csrf');
Route::group(array('before' => 'auth'), function(){
Route::get('dashboard', array('as' => 'panel', 'uses' => 'DashboardController#view_dashboard'));
});
AuthController.php
class AuthController extends Controller {
public function getLogin(){
return View::make('users.login');
}
public function postLogin(){
$rules = array('username' => 'required', 'password' => 'required');
$validator = Validator::make(Input::all(), $rules);
if($validator->fails()){
return Redirect::route('login')->withErrors($validator);
}
$auth = Auth::attempt(array(
'username' => Input::get('username'),
'password' => Input::get('password')
), false);
if(!$auth){
return Redirect::route('login')->withErrors(array(
'Maaf anda bukan sebagai admin..'
));
}
//return "Success";
return Redirect::to('dashboard');
}
}
DashboardController.php
class DashboardController extends Controller {
public function view_dashboard(){
return View::make('dashboard.view_home_admin');
}
}
view_home_admin.blade.php
<h1>Welcome <small>{{ ucwords(Auth::user()->username) }}</small></h1>