How can I invoke the create method to register a user from within a controller.
A user will already be logged in when register the new user.
When doing:
User::create([
...
]);
The password is not hashed, so the register procedure must be done with another method call. In the postRegister method used by the default register process, there is this line
Auth::login($this->create($request->all()));
So how can I invoke
$this->create($request->all())
From with my custom controller and what parameters does it require.
Any ideas
An thanks in advance for any feedback.
/**
* Invites a new user to the current users company.
* #param Request $request
* #return mixed
*/
public function employeeInvite(Request $request) {
$this->validate($request, [
'email' => 'required|email',
]);
// TODO: Check user is authorized to send invites
$user = $this->users->getUserByEmail($request->email); // get user
if($this->userExists($user)
&& $request->user()->email != $request->email
&& $this->userHasInvite($user->id, $request->user()->company_id) == false)
{
// send invite
if($this->sendInvite($request->user()->company_id, $user->id)) {
// if worked, create succses method to send back to the user
}
} else
{
// create user
$userData = [
'email' => $request->email,
'password' => $this->random_password(6),
];
$newUser = User::create($userData);
// send invite
$this->sendInvite($request->user()->company_id, $userData->id);
}
return redirect('members/company');
} // end function employeeInvite
The User::create() method doesn't hash passwords by itself, so you will have to do it yourself.
Laravel's hashing function is bcrypt(), so your $userData array should look like this:
$userData = [
'email' => $request->email,
'password' => bcrypt($this->random_password(6)),
];
Related
I'm using Laravel 5.8, I have a single page that has both the Registration and Login forms (2 separate forms posting to the respective endpoints/controllers)
My Registration Form posts to the Auth/RegistrationController as provided by Lavarel Auth.
I would like to change the behaviour so that on an unsuccessful registration attempt it will add an additional parameter to redirect url so I know which form to apply to validation feedback too.
I'm already aware of the redirectTo variable this appears to be for successful requests though
You need to override the Auth/RegistrationController::register method, take a look at the default code provided by the framework and adjust it to your needs something like this:
public function register(Request $request) {
if ($this->validator($request->all())->fails()) {
return redirect('/foo?bar=1');
}
// Copy the default behaviour here
...
// or you can just
return parent::register($request);
}
You can simply overwrite parent function to create new user in same
Auth/RegistrationController create new method as
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
Here, in '$data' variable you will get all of the parameters which you have passed through form.
For error checking you can just check for,
Laravel global error variable $errors is null or not
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
if(!empty($errors)){
if($data['form'] == 'form_1'){
$redirectTo = 'fitst_form'
}
else if($data['form'] == 'form_2'){
$redirectTo = 'second_form'
}
}
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
I hope this will solve your problem
You have to set register method in app/Http/Controllers/Auth/RegisterController.php
protected function register(Request $request)
{
$errors = ['error'=>'yout errors list];
if(!empty($errors)){
return redirect()->route('/register-errorpage')->withInput()->withErrors($errors);
}
}
I'm building a registration method for my API using passport. When the user makes his registration, I want to return him the access token, similar when we ask for an access token. For this 'm using grant password clients.
What I've done is to ask in the data of the registration the client_id along the client_secret.
Then what I'm looking is that my validation rules are able to validate that the client_secret, corresponds to the client_id.
Here is my registration method:
/**
* Register a new user in the system.
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$vb = User::ValidationBook();
$data = $request->validate($vb["rules"], $vb["messages"]);
// Neccesary data to get a token at registration
$password = $data["user"]["password"];
$clientId = $data["user"]["client_id"];
$clientSecret = $data["user"]["client_secret"];
// If validation passes, create user
$user = $this->userService->store($data);
$request->request->add([
'grant_type' => 'password',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'username' => $user->email,
'password' => $password,
'scope' => null,
]);
// Fire off the internal request.
$token = Request::create(
'oauth/token',
'POST'
);
return \Route::dispatch($token);
}
And here is the reduces version of my User model, I've all the rules in the validation book method.
class User extends Authenticatable
{
/**
* Returns an array that contains two indexes:
* 'rules' for the validation
* 'messages' messages given by the validation
*
* #return array
**/
public static function ValidationBook($except = [], $append = [])
{
$book = ['rules' => [], 'messages' => []];
$book['rules'] = [
... the other rules
//Extra data for register
'user.client_id' => 'required|exists:oauth_clients,id',
'user.client_secret' => 'required|exists:oauth_clients,secret'
];
$book['messages'] = [
... the other messages
// Extras
'user.client_id.required' => 'The client id is required',
'user.client_secret.required' => 'The client secret is required',
];
if (!empty($except)) {
$except = array_flip($except);
$book['rules'] = array_diff_key($book['rules'], $except);
}
if (!empty($append)) {
$book = array_merge_recursive($book, $append);
}
return $book;
}
}
How could I add a rule to the user.client_secret rule to validate that the secret corresponds to that specific id?
Probably this is not the best option to return the access token after the registration, and If there is a simple way to avoid it I'll be glad to learn about it.
Thanks in advance.
The solution was simple. On my validation rules, on the user.client_secret, I add the following values:
$book['rules'] = [
... the other rules
'user.client_id' => 'required|exists:oauth_clients,id',
'user.client_secret' => 'required|exists:oauth_clients,secret,id,'
];
In this, next to the validation of existence of the secret, I add the query to check all the records with a specified id.
Then before the validation I add the desired id to the rule:
$vb = User::ValidationBook();
$vb["rules"]["user.client_secret"] .= $request->input("user")["client_id"];
$data = $request->validate($vb["rules"], $vb["messages"]);
I have two tables the first one is the user table which have these property id, username, email,remember_token, createdat, updateat another table is called received_pay having id, email, token my task is to check if the email, and token entered by the user must match the ones in received_pay otherwise new user is not created, thanks for your time in advanced,
I'm trying to create new user on a condition that if there is data in another table then new user is created otherwise not I have put my code inside if else statement and is throwing errors.
my function for creating new user is listed below:
protected function create(array $data)
{
/*$exists = \DB::table('received_pay')->where('email', $data['email'])->first(); */
$exists=\DB::table('received_pay')->where('email', '=', $data['email'])->where('token', $data['token'])->exists();
if ($exists === null)
{
// user doesn't exist
return User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'token' => $data['token'],
]);
}
else
{
return null;
}
}
I think that the best approach in Laravel is create a middleware to protect this url. If you already have this create user feature working is better don't modify it.
So the first step would be create a middleware (https://laravel.com/docs/5.5/middleware) to add your safeguard, something like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckPayment
{
public function handle($request, Closure $next)
{
$payment = \DB::table('received_pay')->where('email', $request->email)->where('token', $request->token]);
if (!$payment->count()) {
return redirect('no-payment');
}
return $next($request);
}
}
Then you would need to create a route to handle this invalid creation users (this no-payment url).
And finally you can protect your create-user url in route, by adding your middleware in your kernel.php file...
protected $routeMiddleware = [
...
'payment' => \App\Http\Middleware\CheckPayment::class,
];
and in your web.php route file:
Route::post('user', 'UserController#create')->middleware('payment');
In this way your code will look cleaner, tidier, and closer to the way Laravel works.
I hope it would work fine for you.
If you wish to do it with if statement then do it like below
protected function create(array $data)
{
/*$exists = \DB::table('received_pay')->where('email', $data['email'])->first(); */
$exists=\DB::table('received_pay')->where('email', '=', $data['email'])->where('token', $data['token']);
if (!$exists->count())
{
// user doesn't exist
return User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'token' => $data['token'],
]);
}
else
{
return null;
}
}
the count() in the if is to make the statement evaluate true if the data exists and false otherwise and create the new user.
I think that solves your problem.
so this is my register controller
protected function validator(array $data)
{
return Validator;
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
register here
}
I want to add a referral system to this process basically when registering user might send a refer_id (id of a user who has referred this user to website), I'll check that refer id and if it was valid I'll do some my thing
I want to change my validation function to something like
protected function validator(array $data)
{
$validation = Validator::make($data, [
'email' => ['required' ,'email' , 'max:255', Rule::unique('users')->where('rep_id' , $this->rep->id) ] ,
'password' => 'required|string|min:6|confirmed',
'name' => 'required|max:255',
'last_name' => 'required|max:255',
'refer_id' => 'present|numeric',
]);
if(isset($data['refer_id']))
{
$refer = User::find($data['refer_id']) ;
if($refer)
{
// return error : refer id is wrong !
}
}
return $validation ;
}
my problem is this part
// return error: refer id is wrong!
how can I return registering the user with this error back to view or add this error to validation errors?
Laravel has a clean approach to do this
try this
'refer_id' => 'nullable|exists:users,id'
or may be
'refer_id' => 'present|numeric|exists:users,id'
Trying my hand on learning laravel.
I have a user form which post to this route
Route::post('users/add','usersController#store')->middleware('admin');
The store function in the usersController calls another function called validateForm which basically validates the input from the form ,like so
class usersController extends Controller
{
/*
*Store a user in database
*/
function store(){
$input=Request::all();
// create the validation rules ------------------------
$rules = array(
'name' => 'required', // just a normal required validation
'lastname' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the users table
'password' => 'required',
);
$validationResponse=$this->validateForm($input,$rules);
if($validationResponse=="passed"){
$user=new \App\User;
$user->name=$input['name'];
$user->email=$input['email'];
$user->lastname=$input['lastname'];
$user->password=\Hash::make($input['password']);
$user->userlevel=isset($input['isAdmin'])?1:0;
$user->save();
return redirect('users');
}
else{
return Redirect::to('users/create')
->withErrors($validationResponse)->withInput();
}
}
/*
*validate user form input
*/
function validateForm($input,$rules){
// do the validation ----------------------------------
// validate against the inputs from our form
$validator = Validator::make($input, $rules);
// check if the validator failed -----------------------
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
return $messages;
}
else{
return 'passed';
}
}
}
Now this is fine for accesing from the userController, but what if I have another controller say projectsController and I want to access the same funtion i.e. validateForm
Where I should put this common function and how can I access it from any controller?
Laravel built in answer to this is Form Request
Just create a form request using php artisan make:request UserCheck, and put in your validation rules in the method rules
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
return [
'name' => 'required', // just a normal required validation
'lastname' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the users table
'password' => 'required',
]; }
And call it
/*
* Store a user in database
*/
public function store(UserCheck $request)
{
// The incoming request is valid...
}