Laravel 5.7 - Verification email is not sent - laravel

I've upgraded my laravel instance from version 5.6 to version 5.7. Now I try to use the built-in email verification from laravel.
My problem is that I don't get an email after successful registration when I use the "resend" function the email arrives.
What is the problem?

I had this exactly same problem. That is default code from Laravel.
In order to send the email after successful registration you can do this workaround:
at App\Http\Controllers\Auth\RegisterController
change this:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
to this:
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$user->sendEmailVerificationNotification();
return $user;
}

I also have had the same issue. As I checked the source code, it isn't necessary to implement to call the sendEmailVerificationNotfication() method, you just should add the event handler to your EventServiceProvider.php, as because of your event handler was previously created, so Larael can't update that. It should look like this:
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];

If you have a custom registration page, you could just fire the event after you have created the user like so:
event(new Registered($user));

in case somebody else is looking for a solution for the same problem.
please read the documentation, it explains exactly what needs to be done to solve this issue
https://laravel.com/docs/5.7/verification
in a nutshell, and if you are already using 5.7 (i.e you have the necessary fields in your users table) all that you need to do is the following:
make your User model implement the MustVerifyEmail interface.
add ['verify' => true] to the Auth::routes method Auth::routes(['verify' => true]);
you can find everything you need about email verification in the link above.

In addition to djug's reply, if you experience the same problem after upgrading from version 5.6, just as I did, you'll find step-by-step guide what to implement here:
https://laravel.com/docs/5.7/upgrade
under the section Email Verification
Hope this helps someone as I was struggling quite some time with this.

I know this post is a bit on the older side but I had a similar issue with Laravel 7. I think Zane's answer above should be the accepted answer. Just to elaborate on that use the following steps. This should be done after installing the auth scaffolding with composer and php artisan. Note: I am by no means a Laravel pro. If there are any issues with my code PLEASE let me know. The more I learn the better I can be.
Prepare the User Model
Ensure your App\User model implements Illuminate\Contracts\Auth\MustVerifyEmail:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
// ...
}
Setup Routes
In routes\web.php change this:
Auth::routes();
To this:
Auth::routes(['verify'=>true]);
After that you can specify which routes need a verified email address by either using middleware directly on a route like this:
Route::get('/profile','ProfileController#index')->middleware('verified');
or you can do it in the controller's constructor function like this:
public function __construct()
{
$this->middleware(['auth','verified']);
}
Modified Register Controller
I'm using the following register controller code. Note the register function contains a call to the following:
event(new Registered($user));
This was the key to getting the initial registration email to send.
Register Controller
Keep in mind this controller was designed to work with a primarily ajax site, thus why the register function returns a json response.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;
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 registration.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::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, [
'first_name' => ['required', 'string', 'max:255'],
'last_name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'phone_number' => ['required', 'numeric', 'min:10'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
'password_confirmation'=> ['required', 'string'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
$user=User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'phone_number' => $data['phone_number'],
'password' => Hash::make($data['password']),
]);
return $user;
}
/**
* Execute registration and login the user
*
* #param array $request
* #return response
*/
public function register(Request $request) {
$validation = $this->validator($request->all());
if ($validation->fails()) {
return response()->json($validation->errors(),422);
}
else{
$user = $this->create($request->all());
event(new Registered($user));
Auth::login($user);
if (Auth::user()){
return response()->json(['success'=>'Registration Successful']);
}
}
}
}

Make sure you have your From Email setup as most SMTP servers won't allow sending from any address. The env config for those are:
MAIL_FROM_ADDRESS=from#domain.com
MAIL_FROM_NAME=Something

Related

Laravel 6 Reset Password Strength

I've not used Laravel before & am getting familiar; I'm on v6.15.1
My issue:
I can't figure out how to change the password length requirements on the 'Reset Password' form.
What I've done:
app/Http/Controllers/Auth/RegisterController.php - This works & the form's minimum password length validation error requires a length of 12
/**
* 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'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:12', 'confirmed'],
]);
}
app/Http/Controllers/Auth/ResetPasswordController.php - This does not work & I'm still getting the validation error "The password must be at least 8 characters."
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Facades\Validator;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* #var string
*/
protected $redirectTo = '/';
/**
* 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, [
'password' => ['required', 'string', 'min:12', 'confirmed'],
]);
}
}
Not entirely sure why yet until I poke around in Laravel more, but apparently the reset password controller uses a 'rules' method instead of valdiation
In app/Http/Controllers/Auth/ResetPasswordController.php
I added the construct method I added the rules method & made the
password 1) require a length of 12 & 2) additional characters, numbers etc
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* #var string
*/
protected $redirectTo = '/';
public function __construct()
{
$this->middleware('guest');
}
// this function is ovverride from ResetsPasswords Traits
protected function rules()
{
return [
'token' => 'required',
'email' => 'required|email',
'password' => 'required|min:12|confirmed|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$/',
];
}
}

Laravel 5.7 not sending verify emails

after successful registration my app doesn't send verification email (It only sends to emails on my domain) and I'm redirected to /email/verify as if it was sent (checked spam and promotion folders). On other hand my forget password system works like a charm so I guess my .env is good.
Here are my routes for auth and verification:
Route::group([
'prefix'=>'{locale}',
'where'=>['locale'=>'[a-zA-Z]{2}'],
'middleware'=>'setlocale',
],function(){
Route::get('/login','Auth\LoginController#showLoginForm')->name('login')->middleware('guest');
Route::post('/login','Auth\LoginController#login')->middleware('guest');
Route::post('/logout','Auth\LoginController#logout')->name('logout');
Route::get('register','Auth\RegisterController#showRegistrationForm')->name('register')->middleware('guest');
Route::post('register','Auth\RegisterController#register');
Route::get('/email/verify', 'Auth\VerificationController#show')->name('verification.notice');
}); //closed group locale
Route::get('email/verify/{id}', 'Auth\VerificationController#verify')->name('verification.verify');
Route::get('email/resend', 'Auth\VerificationController#resend')->name('verification.resend');
When I receive email on my own domain email address it works.
RegisterController.php
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/';
/**
* 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'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
public function redirectTo(){
return route('verification.notice',app()->getLocale());
}
}
Add a routeNotificationForMail() method in your App\User that returns the email address you’d like email notifications sent to. In the code below, my ‘email’ field contains the email address for each user
class User extends Authenticatable implements MustVerifyEmail
{
use Notifiable;
//...
public function routeNotificationForMail($notification)
{
return $this->email;
}
}
Hosting company gave me new different MAIL_HOST it works now, maybe old one was blacklisted or something. Thanks everyone for comments.

Laravel RegisterController route not found

I'm learning Laravel and I'm trying to use Laravel Passport.
When I try to create a new user I'm getting error 404 not found.
RegisterController.php
app/Http/Controllers/Auth
I also have this path for my api controllers
app/Http/Controllers/Api
Route in api.php
Route::post('/create', 'Auth\RegisterController#create');
RegisterController
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
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, [
'username' => ['required', 'string', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
// return Validator::make($data, [
// 'name' => ['required', 'string', 'max:255'],
// 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
// 'password' => ['required', 'string', 'min:6', 'confirmed'],
// ]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'username' => $data['username'],
'password' => Hash::make($data['password']),
]);
}
}
Testing registration with Insomnia
I know I'm not passing any values for registration.
I've tested 127.0.0.1:8000/create¹
I've tested 127.0.0.1:8000/auth/create²
I've tested 127.0.0.1:8000/Auth/create³
I can't see a way to register the user and get the token back. What is wrong? Manual is not clear for begginers.
EDIT 1
Other routes (GET) that you can see in the image are working.
you need to run following artisan command to create auth routes
php artisan make:auth
here is documentation link
https://laravel.com/docs/5.7/authentication#included-routing
Update
for laravel Passport you need to add passport routes like this in AppServiceProvider boot method
Passport::routes();
Read API Authentication documentation carefully everything is there
https://laravel.com/docs/5.7/passport

Laravel Guzzle conflicts with /register Route::auth()

I'm new to use Laravel. I'm using Laravel 5.2. I've implemented Auth for user register and login. It is work properly. After installed Guzzle via composer and after that implementing sending email, it works like a charm. But after try to submit register user, the data which sent via POST form, not saved in table. How to keep data recorded in table meanwhile sending email still works?
AuthController for handling user registration:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\PencapaianBadge;
use DB;
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 = '/';
/**
* 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, [
'first_name' => 'required|max:255',
'last_name' => 'required|max:255',
'username' => 'required|max:10|unique:users',
'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)
{
//Ambil id user dengan menhitung jumlah rows
$id = DB::table('users')->count();
/*PencapaianBadge::create([
'id_user' => $id+1,
'id_badge' => 1,
]);*/
$Pencapaian = new PencapaianBadge();
$Pencapaian->id_user = $id+2;
$Pencapaian->id_badge = 1;
$Pencapaian->save();
return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'role_id' => 2,
'path_image' => 'main/resources/assets/images/user_profiles/default.png',
]);
}
}

Laravel 5.1 - Store Data in Eloquent: Relationships

I folowing Official Laravel 5.1 User Authentication to create User Login and User Register and it is run well.
But now, I add another table, user_detail table, which contain another data of user like first/last name, gender, etc. This table has one to one relationship with user table. And I already defining relationships like hasOne and belongsTo.
I want to ask, how when I registered a new user, the both user and user_detail table is filled? Although the user_detail tables just filled in the 'id' only, because the user table and user_detail table have same id for primarykey and foreignkey.
For reference here my routes:
...
// Registration routes...
Route::get('auth/register', 'Auth\AuthController#getRegister');
Route::post('auth/register', 'Auth\AuthController#postRegister');
...
AuthController:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\UsersDetail;
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;
/**
* Create a new authentication controller instance.
*
* #return void
*/
public function __construct() {
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* 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|confirmed|min:6',
]);
}
/**
* 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']),
]);
}
protected $redirectPath = '/dashboard';
}
Here is one way of doing it.
$user = new \User($data)->save();
$user_detail = new \UserDetail($detail_data);
$user->user_detail()->associate($user_detail);
Okay, I think #ajameswolf method is to update data. What I need is to create a data in two table which have relation.
I use this method in my AuthController.
protected function create(array $data) {
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$user_detail = UsersDetail::create([
'birthOfDate' => null
]);
$user->save();
$user_detail->save();
return $user;
}

Resources