I am currently working on a system where people can submit a registration request. The admin will need to accept the request in order for the user to be able to sign in. In my database, I have a field called is_request and with every registration this field is set by default to 1 (is set by default to 1 in the database) , meaning yes. When a user with this field set to 1, tries to log in, they will need to be notified that their account has not yet been activated. How can I accomplish this?
When the user tries to register the following happens:
protected function create(array $data)
{
$users = User::where('role_id', 1)->get();
$user = User::create([
'firstname' => $data['firstname'],
'lastname' => $data['lastname'],
'email' => $data['email'],
'role_id' => 3,
'activated' => 0,
'user_token' => Str::random(32),
'password' => Hash::make($data['password']),
]);
foreach($users as $admin) {
$admin->notify(new registerRequest($user));
}
Mail::to($user->email)->send(new RegisterRequestSend($user));
return $user;
}
And when the admin in the backend "accepts" the request the field is_request will be set to 0 and the user needs to be able to sign into the app.
The login controller looks like this
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
Update:: DB Table
You could create an global middleware that checks if the user is accepted or not:
namespace App\Http\Middleware;
use Closure;
class CheckIfAccepted
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (auth()->check() && !auth()->user()->isAccepted) {
auth()->logout();
return redirect('not-accepted');
}
return $next($request);
}
}
This middleware will log out any authed user that aren't accepted and redirect them to a route of your choice.
Change auth()->user()->isAccepted to an attribute or method that contains information about the accepted-status.
If you want the middleware to run at every request, you can add it as a global middleware by adding it the the $middleware-array in app/Http/Kernel.php.
You can read more about middleware and how to create them in the docs:
https://laravel.com/docs/master/middleware
First you have to make the admin to update the attributes of the user when they are notified
User::where('id' , $user_id)->update(['is_request' => 0]);
then add this in your login controller
public function credentials(Request $request)
{
$credentials = $request->only($this->username(), 'password');
$credentials = array_add($credentials, 'is_request', 0);
return $credentials;
}
Related
I have this on my controller but the redirection does not work it says Type error: Argument 1 passed to Illuminate\Auth\SessionGuard::login(), I have tried this so far but nothing
<?php
namespace App\Http\Controllers\Auth;
use App\Events\NewUserWasRegistered;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Validator;
use Auth;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
*
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
$rules = [
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
'g-recaptcha-response' => 'required|captcha',
'allow_register' => 'required|accepted',
];
if (app()->environment('local') || app()->environment('testing')) {
unset($rules['g-recaptcha-response']);
}
$data['allow_register'] = config('root.app.allow_register', true);
$messages = [
'allow_register.accepted' => trans('app.allow_register'),
];
return Validator::make($data, $rules, $messages);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
*
* #return User
*/
protected function create(array $data)
{
$user = User::create([
'username' => md5("{$data['name']}/{$data['email']}"),
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'role_id' => $data['role'],
]);
event(new NewUserWasRegistered($user));
if($user){
if ($user->role_id == 0) {
Auth::login($user);
return redirect('user/businesses');
}else if($user->role_id == 1){
Auth::login($user);
return 'Working on..';
}
}
// return $user;
}
}
Can someone please help me I am stuck, I have tried so many things but I am new on coding so maybe you will understand If it is that I am asking too much
App\Models\User must implement the interface/contract Illuminate\Contracts\Auth\Authenticatable.
"If you need to log an existing user instance into your application, you may call the login method with the user instance. The given object must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract. Of course, the App\User model included with Laravel already implements this interface ..."
Laravel 5.7 Docs - Authentication - Manually Authenticating Users - Other Authentication Methods
Side Note:
The create method of that controller is only for taking an array of data and creating a new User and returning that User instance. Nothing else. The registration flow out of the box calls that method, only to create the user. It then does the login and everything else.
I've made a referral system on my laravel project v5.4 but I have 2 issues with that:
My users referral link will load index page of my website instead of loading register page. (How I fix it?)
When user register with referral link nothing will happen in database of the person who invited new user and also new user him/herself. (How I get info in both users tables?)
I simply used this tutorial to get my referral system:
https://brudtkuhl.com/building-referral-system-laravel/
This is my CheckReferral Middleware:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Response;
use Closure;
class CheckReferral
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if( $request->hasCookie('referral')) {
return $next($request);
}
else {
if( $request->query('ref') ) {
return redirect($request->fullUrl())->withCookie(cookie()->forever('referral', $request->query('ref')));
}
}
return $next($request);
}
}
This is my UserController
public function referral() {
$user = User::find(1);
return view('users.referral', compact('user'));
}
Here is my route:
Route::get('/referral', 'UserController#referral')->name('referral');
My RegisterController
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use Cookie;
use DB;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'username' => 'required|string|max:255|unique:users',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'g-recaptcha-response' => 'required|captcha',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$referred_by = Cookie::get('referral');
return User::create([
'name' => $data['name'],
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'affiliate_id' => str_random(10),
'referred_by' => $referred_by,
]);
}
User Model
protected $fillable = [
'name', 'username', 'email', 'password', 'affiliate_id', 'referred_by',
];
And That's it!
if this is for registration the right way to do this is first in your routes you should have a optional input like ..
Route::get('/register/{referral?},'Auth\RegisterController#registerPage');
then in that controller
public function registerPage($referral=0)
{
return view with the $referral variable ..
}
in your view .. your form should look like this ..
<form action="/register/{{ referral }}" method="post" ..... >
back to your route ..
Route::post('/register/{referral},'Auth\RegisterController#doRegister');
in your controller again ..
public function doRegister(Request $request, $referral)
{
$request->merge(['referred_by' => $referral]);
}
so your referred_by is either 0 or other value .. it's up to you how you handle the validation ..
Add register page url in the value in this part -> url('/')
#if(!Auth::user()->affiliate_id)
<input type="text" readonly="readonly"
value="{{url('/').'/?ref='.Auth::user()->affiliate_id}}">
#endif
Question number 1:
I think you should add {{url('/register')}} here instead of {{url('/')}} to make it look this way:
#if(!Auth::user()->affiliate_id)
<input type="text" readonly="readonly"
value="{{url('/register').'/?ref='.Auth::user()->affiliate_id}}">
#endif
If that's how your register route endpoint is defined.
i have a question, i want to redirect users to diferent pages after login based in the role, if is admin redirect to admin/users if is normal redirect to admin/norma for example i have the next files
LoginController.php
<?php
namespace App\Admin\Http\Controllers\Auth;
use App\Admin\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = 'admin/users';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
/**
* Validate the user login request.
*
* #param \Illuminate\Http\Request $request
* #return void
*/
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'required', 'password' => 'required', //'g-recaptcha-response' => 'required|recaptcha',
]);
}
}
And i use Laravel 5.3 and the Shinobi Package for roles and permissions https://github.com/caffeinated/shinobi
I already create 4 roles in the system database table roles - Administrador/Free/Gold/Diamond
I thinks is something how this
if($user->rol = 'Administrador){
protected $redirectTo = 'admin/users';
}else{
protected $redirectTo = 'admin/normal';
}
But i dont know how exactly make to work, thanks for all.
What you're looking for is the authenticated method override. Larvel calls this method after successful login to perform additional checks. You even get the user object and request object. You can perform the user role check and set the redirect path accordingly.
Add this to your LoginController
protected function authenticated(Request $request, $user)
{
if ($user->role == 'admin') {
$this->redirectTo = 'admin/dashboard';
} else {
$this->redirectTo = 'user/dashboard';
}
}
Edit : Since you're using the shinobi package. You need to do the role check like so
if ($user->isRole('admin')) {
}
I already solve my question in base to shinobi roles and the help of Sandeesh
I add this to my loginController.php
use Caffeinated\Shinobi\Models\Role;
use Caffeinated\Shinobi\Models\Permission;
and the function authenticated is now
protected function authenticated(Request $request, $user)
{
if( $user->isRole( 'administrador' ) ) {
$this->redirectTo = 'admin/dashboard';
} else {
$this->redirectTo = 'user/dashboard';
}
}
And now is working thanks for all :D
I want my AuthController to check for few conditions and redirect to the respected routes accordingly. I want to check the if the logged in user's DB has particular columns are not empty. If its not empty i am redirecting to home page else I am redirecting to another route. I have used postLogin method. the issue here is its not checking the condition at all and directly redirecting to home even if the condtion fails. I tried to log in with new users whose details in DB are not filled , then also it redirected me to the home page and same happened with user who has his personal details filled in DB
here is the code of my AuthController
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
//protected $redirectTo = '/user-prof';
public function postLogin(Request $request)
{
$email = $request->email;
$user = \Auth::user();
if(($user->username && $user->phone && $user->bio && $user->dobday && $user->dobmonth && $user->dobyear && $user->firstname
&& $user->lastname && $user->topics && $user->nationality)!= NULL)
{
redirect('home');
}
else
{
redirect('/user-prof');
}
return $this->login($request);
}
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
}
I also want to know if i am checking the DB column data in the right way in IF condition inside the postLogin() method.
You probably mean to do those checks after the user has been 'authenticated' and logged in. You can define a authenticated method on your AuthController that will be called by handleUserWasAuthenticated after the user has been authenticated.
Something like this perhaps. (Get the user's attributes, only get the ones we want to check, use array_filter to remove the nulls, see if all the required fields are there).
protected function authenticated($request, $user)
{
$required = [
'username', 'phone', 'bio', 'dobday', 'dobmonth', 'dobyear',
'firstname', 'lastname', 'topics', 'nationality'
];
$userAtts = array_filter(array_only($user->toArray(), $required));
if (count($userAtts) != count($required)) {
return redirect('/user-prof');
}
return redirect('home');
}
This doesn't change any methods the AuthController already has via the traits, it just adds a method that handleUserWasAuthenticated will check to see if exists, and if so will call it.
Illuminate\Foundation\Auth\AuthenticatesUsers#login -> #handleUserWasAuthenticated
If you intend on 'caging' the user until these fields are filled in, then I would go with a middleware option similar to what #Ravi's answer is saying, but would have to be applied to a lot of routes.
Do not override the method in Authcontroller. Use an after-middleware on postLogin route to check the conditions and route accordingly.
https://laravel.com/docs/5.2/middleware
There is one other way to do it; however, I wouldn't suggest you do it. You may modify the RedirectsUsers trait. It is a Laravel file and will be defaulted back to original at every composer update. Although you can have a look at it to understand the redirection
https://github.com/laravel/framework/blob/5.1/src/Illuminate/Foundation/Auth/RedirectsUsers.php
Here is my routes.php file
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/login', function(){
return view('auth.login');
});
Route::post('/login', 'Auth\AuthController#authenticate');
Route::get('/home', 'HomeController#index');
Here is my AuthController.php file
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Auth;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
protected $redirectTo = '/';
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'user_name' => 'required|max:255|unique:users',
'full_name' => 'required|max:255',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
return User::create([
'user_name' => $data['user_name'],
'full_name' => $data['full_name'],
//'password' => bcrypt($data['password']),
'password' => $data['password'],
]);
}
//Auth::attempt(['user_name' => $user_name, 'password' => $password])
public function authenticate()
{
if (Auth::attempt($request->all()) {
var_dump(Auth::user())
if(Auth::user()->type == 'admin') {
return "Welcome company admin let's create some user for your company";
# code...
} elseif(Auth::user()->type == manager) {
return "Welcome manager let's manage your coaches";
}elseif(Auth::user()->type == 'counterman'){
return "Welcome counter person let's sell some ticket's";
}else
{
return "Welcome online user let's make a relationship with me";
}
return "Gonnnaaa";
//return redirect()->intended('dashboard');
}else
{
return "you are fucked";
}
}
}
In my project I want redirect my user to different pages according to there type . I tried to implement this in different ways . At last I tried to use authenticate method inside AuthController as suggested in laravel doc's but I am getting AuthController not exist error . What wrong I am doing and what can be better approach in my case ? thanks in advance . I have not edited anything except AuthController and routes.
If you don't want to implement something new by yourself, you could create a new TypeBasedAuthController that extends the AuthController.
Then, you would decorate its parent by implementing a postLogin method that calls the parent postLogin. After the login logic, you could change the $redirectTo property as you wish.
It should make sense... :)
EDIT: take a look to this link if you want to know something more about the decorator pattern in PHP :)
EDIT2 - Important: after another deeper search, I have found a better solution. All you have to do is to overwrite this method in your new TypeBasedAuthController.
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
// HERE: control the user that has logged in and change the value
// of $this-redirectTo property accordingly.
return redirect()->intended($this->redirectPath());
}
It should be quite clear now.