Pro*_*ers 10 php authentication laravel laravel-5
我是一个家庭爱好者,正在学习Laravel,目前正在版本中5.3.我正在使用Mac,也不homestead是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',
];
}
Run Code Online (Sandbox Code Playgroud)
还有一个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';
}
}
?>
Run Code Online (Sandbox Code Playgroud)
如您所见,我使用的bcrypt()是哈希方法.
但是,这个问题是,它总会导致失败.
我检查了以下链接:
PS这些链接似乎很难遵循,因为我没有使用Input该类.
问题在于login注册后将用户重定向到路由的方式。您错误地假设$request数据将伴随重定向。
让我们假设这样的场景:一个请求被分派到postRegister与方法name,email和password领域。控制器创建用户并将其保存到数据库中。然后,它将尚未通过身份验证的用户重定向到该login路由。该postLogin方法被触发,但是这次没有请求数据。结果,Auth::attempt($credentials)失败了,您会Failure在屏幕上看到那种讨厌的东西。
如果dd($credentials)在创建数组后添加一个权限,则会看到它没有值:
public function postLogin(Request $request)
{
$credentials = [
'username' => $request['username'],
'password' => $request['password'],
];
// Dump data
dd($credentials);
if (Auth::attempt($credentials)) {
return redirect()->route('dashboard');
}
return 'Failure';
}
Run Code Online (Sandbox Code Playgroud)
它将返回如下内容:
array:2 [
"username" => null
"password" => null
]
Run Code Online (Sandbox Code Playgroud)
您不能使用自定义请求数据进行重定向(除非使用URL中的querystring进行重定向),无论如何。这不是HTTP的工作方式。除了请求数据,您甚至无法使用自定义标头进行重定向。
现在您知道了问题的根源是什么,让我们看看有什么解决方案。
如果要保留此结构,则需要将请求的数据刷新postRegister()到会话中(在请求之间保持不变),然后postLogin()使用SessionFacade,session()Helper或实际的Illuminate\Session\SessionManager类在方法中检索它。
这就是我的意思是:
(我稍微修改你的代码;下降的其他变量,使之成为律位清洁器等)
public function postRegister(Request $request)
{
// Retrieve all request data including username, email & password.
// I assume that the data IS validated.
$input = $request->all();
// Hash the password
$input['password'] = bcrypt($input['password']);
// Create the user
User::create($input);
// Redirect
return redirect()
// To the route named `login`
->route('login')
// And flash the request data into the session,
// if you flash the `$input` into the session, you'll
// get a "Failure" message again. That's because the
// password in the $input array is already hashed and
// the attempt() method requires user's password, not
// the hashed copy of it.
//
->with($request->only('username', 'password'));
}
public function postLogin(Request $request)
{
// Create the array using the values from the session
$credentials = [
'username' => session('username'),
'password' => session('password'),
];
// Attempt to login the user
if (Auth::attempt($credentials)) {
return redirect()->route('dashboard');
}
return 'Failure';
}
Run Code Online (Sandbox Code Playgroud)
我强烈建议您不要使用这种方法。这样postLogin(),本应负责登录用户的方法的实现与不好的会话数据结合在一起。这样,您将无法postLogin独立于使用postRegister。
这是一个更好的解决方案。如果您确定注册后需要立即登录用户,为什么不这样做呢?
请注意,Laravel自己的身份验证控制器会自动执行此操作。
顺便说一句,这就是我的意思:(
理想情况下,它应该分为多种方法,就像Laravel自己的身份验证控制器一样。但这只是入门的一个示例。)
public function postRegister(Request $request)
{
$input = $request->all();
$input['password'] = bcrypt($input['password']);
User::create($input);
// event(UserWasCreated::class);
if (Auth::attempt($request->only('username', 'password'))) {
return redirect()
->route('dashboard')
->with('Welcome! Your account has been successfully created!');
}
// Redirect
return redirect()
// To the previous page (probably the one generated by a `getRegister` method)
->back()
// And with the input data (so that the form will get populated again)
->withInput();
}
Run Code Online (Sandbox Code Playgroud)
但是,它远非完美!还有许多其他方法可以解决此问题。一种可能是使用事件,在失败时引发异常并使用自定义异常进行重定向。但是我不打算探讨它们,因为已经有一个为此完美设计的解决方案。
如果您想编写自己的身份验证控制器,那很好。您将在此过程中学到很多东西。但我强烈建议阅读Laravel自己的验证码,尤其是RegistersUsers和AuthenticatesUsers特点,以便从中吸取教训。
还有一个音符;您无需Illuminate\Auth\Authenticatable在User模型Authenticatable中使用该特征,因为已经在扩展使用该特征的特征。
| 归档时间: |
|
| 查看次数: |
22525 次 |
| 最近记录: |