我是家庭爱好者,正在学习Laravel,目前版本为 5.3
. 我使用的是Mac,既不是_2673944也不是 vagrant
.
我目前正在开发一个使用登录和注册系统来创建用户的网站 .
我已经使用 php artisan migrate
在本地操作我的数据库 .
如下所列,它有三个字段,即:
-
电子邮件
-
用户名
-
密码
我有一个 User
模型(users.php):
<?php
namespace blog;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
class User extends Model implements Authenticatable {
use \Illuminate\Auth\Authenticatable;
use Notifiable;
protected $fillable = [
'username', 'email', 'password',
];
}
还有一个 UserController
类(UserController.php):
<?php
namespace blog\Http\Controllers;
use Auth;
use blog\User;
use Illuminate\Http\Request;
class UserController extends Controller {
public function postRegister(Request $request) {
$username = $request['username'];
$email = $request['email'];
$password = bcrypt($request['password']);
$user = new User();
$user->email = $email;
$user->username = $username;
$user->password = $password;
$user->save();
return redirect()->route('login');
}
public function postLogin(Request $request) {
$credentials = [
'username' => $request['username'],
'password' => $request['password'],
];
if(Auth::attempt($credentials)) {
return redirect()->route('dashboard');
}
return 'Failure';
}
}
?>
如您所见,我使用 bcrypt()
作为我的哈希方法 .
但是,这个问题是,它总会导致失败 .
我检查了以下链接:
附:这些链接似乎很难遵循,因为我没有使用 Input
类 .
3 回答
问题在于您在注册后将用户重定向到
login
路由的方式 . 您错误地假设$request
数据将伴随重定向 .让我们假设这种情况:使用
name
,email
和password
字段将请求分派到postRegister
方法 . 控制器创建用户并将其保存到数据库中 . 然后,它将尚未通过身份验证的用户重定向到login
路由 .postLogin
方法被触发,但这次没有请求数据 . 结果,Auth::attempt($credentials)
失败,你在屏幕上得到了令人讨厌的Failure
.如果在创建数组后立即添加
dd($credentials)
,您将看到它没有值:它将返回如下内容:
您不能使用自定义请求数据重定向(除非使用查询字符串作为URL的一部分),无论如何 . 这不是HTTP的工作原理 . 请求数据,you can't even redirect with custom headers .
既然您知道问题的根源是什么,那么让我们看看有哪些方法可以解决它 .
1.使用闪烁数据重定向
如果要保留此结构,则需要将
postRegister()
的请求数据刷新到会话中(在请求之间保持不变),然后使用Session
facade,session()
helper或实际的Illuminate\Session\SessionManager
类在postLogin()
方法中检索它 .这就是我的意思:
(我稍微修改了你的代码;删除了额外的变量,使它变得更清晰,等等)
我强烈建议您不要使用这种方法 . 这样,应该对登录用户负责的
postLogin()
方法的实现与会话数据相结合,这是不好的 . 这样,您就无法独立于postRegister
使用postLogin
.2.注册后立即登录用户
这是一个稍好的解决方案;如果您决定在注册后立即登录用户,为什么不这样做呢?
请注意Laravel自己的身份验证控制器does it automatically .
顺便说一句,这就是我的意思:
(理想情况下,这应该分解为多种方法,就像Laravel 's own authentication controller. But it'只是一个让你入门的例子 . )
但是,它仍然是 far from perfect !还有很多其他方法可以解决这个问题 . 一个人可能正在使用events,在失败时抛出exceptions和redirecting using custom exceptions . 但我'm not gonna explore them as there'已经a solution perfectly designed for this .
如果你想编写自己的身份验证控制器,那么's fine. You'将会学到很多东西 . 但我强烈建议阅读Laravel自己的身份验证代码,尤其是RegistersUsers和AuthenticatesUsers特征,以便从中学习 .
再说一遍;你在
User
模型中不需要那个Illuminate\Auth\Authenticatable
特征,因为它已经扩展了使用该特征的Authenticatable .每次插入行bcrypt(pass)时都应该对密码进行哈希处理 . Auth :: attempt假定从数据库中检索的密码是经过哈希处理的
Auth::attempt
使用\Hash::make($someString)
生成哈希 . 您也应该使用它来从相同的字符串生成相同的哈希值(我假设种子与bcrypt()
函数不同) .所以改变这一行:
至: