请一些Laravel知识分子给我指出正确的方向。为了DRY的利益和使用Laravels的出色助手等,我想知道是否有人对此有解决方案:对于注册一个新用户,所有的例子和文档,我能找到,似乎有一个形式,要求电子邮件,用户名等验证(或不验证)输入并创建用户并将其添加到db。一些示例继续向新用户发送欢迎电子邮件。我对这个过程有一个问题,因为任何人都可以使用任何电子邮件地址注册,即使这不是他们的。因此,我希望将电子邮件与激活链接合并,以确保在用户激活之前拥有地址的所有权。
是我错过了什么,还是Laravel有某种令牌生成功能,可以帮助生成令牌和/或发邮件给新用户?我设置了密码提醒,看到有一个很棒的方法:password::提醒它生成令牌等并向用户发送电子邮件,并且想知道是否有这样的东西可以用于激活电子邮件。
如果不是唯一的方法,我可以看到这是可能的是添加2个字段到数据库(令牌和user_activated),然后在控制器中,当用户被保存时,以某种方式生成一个令牌,并保存它和一个值到user_activated字段。然后发送一封带有控制器链接的电子邮件,该控制器在点击时检查令牌,匹配用户并更新user_activated字段并记录用户登录等。
多谢
对于旧版本的Laravel,我留下了我的旧答案,但是,对于Laravel 5.2+,你只需要做:
php artisan make:auth
php artisan migrate
这是我写的一个通过电子邮件验证用户身份的程序包(包括重新发送确认和密码重置):
你可以在这里看到一个演示:
https://signup.edenwired.com/源代码:
https://github.com/iateadonut/signup/当然,如果您打算在自己的脚本中使用这些代码片段,而不是下载我的脚本,那么您应该消除对名称空间iateadonut/signup/ 的引用。这是登录表单(一个刀片模板);如果你登录了,它会给你一个退出的链接;否则它会给你一个登录表单:
@if ( Auth::guest() )
<form method='POST' action="{{ URL::to('/login') }}">
<label class='loginLabel'>email: </label>
<input name='email' id='email'> <br />
<label class='loginLabel'>password: </label>
<input type='password' name='pword' id='pword'> <br />
<label class='loginLabel'><span class='labelHolder'>.</span></label>
<input type=checkbox> Remember Me
<input type=submit value='Log In' name='remember'>
</form>
@if ( isset( $loginMessage ) )
<p>{{ $loginMessage }}</p>
@endif
<label class='loginLabel'><span class='labelHolder'>.</span></label>
<a href='signup'>Sign up / Reset Password</a>
@else
You are logged in. {{ HTML::link('logout', 'Log out.') }}
@endif
这是登录和注销的路由(/meat是经过身份验证的用户将被重定向到的目录)。
如果用户没有登录,他将被带到网站root:
Route::filter('auth', function() {
if (Auth::guest()) return Redirect::to('/');
});
如果用户去'logout',我们首先检查他是否登录;如果是,注销他;然后,无论哪种方式,将用户返回到网站根目录:
Route::get( 'logout', function(){
if ( !Auth::guest() ) Auth::logout();
return Redirect::to('/');
});
www.webroot.com/login:
登录例程Route::get ('login', function()
{
return Redirect::to('/');
});
这是来自登录表单的内容。注意Auth::attempt也接受参数Input::get('remember')——这是Laravel用来记住登录的内置函数。如果登录失败,我们嵌套loginForm(如上)并给它一个错误消息:
Route::post( 'login', function()
{
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('pword'),
'id_code' => '1'
);
if ( Auth::attempt($credentials, Input::get('remember')) )
{
return Redirect::to('/meat');
} else {
return View::make('signup::home')
->nest('loginForm', 'signup::loginForm')
->with('loginMessage', 'Invalid Login.');
}
});
这是注册表单;项目中的一个包括密码恢复和重新发送确认邮件,但我们将忽略这个答案中的那些;还不包括javascript,它可以确认有效的电子邮件并检查两个密码是否相同。
在源代码中,也有一些jquery连接到数据库,以确保用户想要的电子邮件地址尚未被使用:
<div class='signupbox'>
<form action='signup2' method='post'>
your email address: <br>
<div id='EMAIL' style='float:right;'></div><input type='text' name='email' id='email2'><br>
password: <br>
<div id='PW1' style='float:right;'></div><input type=password maxlength=20 name='pw' id='pw' ><br>
confirm password: <br>
<div id='PW3' style='float:right;'></div><input type=password maxlength=20 name='pw2' id='pw2' ><br>
<input type='submit' value='create account' disabled=true id='createAccount' class='createAccount'></form>
<p>Use this when signing up for a new account.</p>
</div>
这里有两个注册路径:
这只是将用户重定向到注册表单:
Route::get( 'signup', array( 'uses' => 'IateadonutSignupSignupController@showSignup' ));
这个接受注册表单的发布:
Route::post( 'signup2', array('uses' => 'IateadonutSignupSignupController@signup2'));
注册控制器看起来像这样;首先,它生成一个25个字符的随机字符串,然后将该字符串和电子邮件地址以及散列密码输入数据库,然后向用户发送一封电子邮件,以便他可以确认该电子邮件地址是他的:
public function signup2()
{
//GENERATE $newcode - RANDOM STRING TO VERIFY SIGNUP
for( $code_length = 25, $newcode = ''; strlen($newcode) < $code_length; $newcode .= chr(!rand(0, 2) ? rand(48, 57) : (!rand(0, 1) ? rand(65, 90) : rand(97, 122))));
$user = new User;
$user->email = Input::get('email');
$user->password = Hash::make( Input::get('pw') );
$user->id_code = $newcode;
$user->save();
$data = array(
'email' => Input::get('email'),
'clickUrl' => URL::to('/') . '/confirm/' . $newcode
);
Mail::send('signup::emails.signup', $data, function($message)
{
$message->to( Input::get('email') )->subject('Welcome!');
});
return View::make('signup::signup2')->with($data);
}
和电子邮件的视图必须包含一个链接与id_code已创建(注册.刀片.php在视图/电子邮件目录):
Please click on:<br /><br />
{{ HTML::link( $clickUrl ) }} <br /><br />
to confirm your account.
当然,要把这个放到数据库中,你需要一个表;以下是迁移的一些细节(字段pw_code用于密码恢复,在本回答中没有讨论):
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('email', 100)->unique();
$table->string('password', 64);
$table->string('remember_token', 100);
$table->string('id_code')->default(0);
$table->string('pw_code')->default(0);
$table->timestamps();
});
下面是确认邮件链接到的路由:
Route::get( 'confirm/{id_code}', array( 'uses' => 'IateadonutSignupSignupController@confirm' ));
注册控制器中的confirm()函数如下所示:
public function confirm( $id_code )
{
if ( $user_info = User::where('id_code', '=', $id_code)->first() )
{
$uid = $user_info->id;
$email = $user_info->email;
$data = array(
'id_code' => $id_code,
'user_id' => $uid,
'email' => $email
);
$user = User::find($uid);
$user->id_code = 1;
$user->save();
Auth::login( User::find($uid) );
return View::make('signup::confirmed')->with($data);
} else {
return View::make('signup::confirmedError')->nest('loginForm', 'signup::loginForm');
}
}
最后但并非最不重要的是,因为你正在发送密码,你肯定希望使用安全连接;确保在filters.php:
中有这样的内容App::before(function($request)
{
if( ! Request::secure())
{
return Redirect::secure(Request::path());
}
});
我想就是这样!Laravel让它变得非常简单!
是的,你可以自己构建这个包,或者使用下面这个包:cartalyst/哨兵.
它们有这个内置的功能。
编辑如果你仍然想要一个解决方案,看看这里:
https://github.com/BenBradleySmith/email-verification