私は家の趣味で、現在バージョン_5.3
_のLaravelを勉強しています。 Macを使用していますが、Homestead
もvagrant
も使用していません。
現在、ログインと登録システムを使用してユーザーを作成するWebサイトで作業しています。
_php artisan migrate
_を使用して、データベースをローカルで操作しました。
以下にリストされているように、3つのフィールドがあります。
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
クラスを利用していないため、これらのリンクをたどるのは非常に困難です。
問題は、登録後にユーザーを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';
}
_
次のようなものが返されます。
_array:2 [
"username" => null
"password" => null
]
_
(URLの一部であるクエリ文字列を除いて)カスタムリクエストデータでリダイレクトすることはできません。 HTTPの仕組みではありません。データは別にして、 カスタムヘッダー でリダイレクトすることもできません。
問題の原因がわかったので、それを修正するためのオプションを見てみましょう。
この構造を保持する場合は、postRegister()
のリクエストデータをセッションにフラッシュし(リクエスト間で永続的)、Session
を使用してpostLogin()
メソッドで取得する必要があります。 facade、session()
ヘルパー、または実際の_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';
}
_
このアプローチを使用しないことを強くお勧めします。このようにして、ユーザーのログインを担当することになっている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();
}
_
それでも、完璧からはほど遠い!これに取り組むには他にも多くの方法があります。 1つは events を使用し、失敗すると exceptions をスローし、 カスタム例外を使用してリダイレクトする 。しかし、 this 向けに完全に設計されたソリューションが既にあるので、それらを探索するつもりはありません。
独自の認証コントローラーを作成する場合は、問題ありません。あなたは道に沿って多くを学びます。しかし、Laravel自身の認証コード、特に RegistersUsers
および AuthenticatesUsers
の特徴を読むことを強くお勧めします。
そしてもう一つの注意; User
モデルでは、その特性を使用する Authenticatable
を既に拡張しているため、その_Illuminate\Auth\Authenticatable
_特性は必要ありません。
行bcrypt(pass)を挿入するたびにパスワードをハッシュする必要があります。 Auth :: attemptは、データベースから取得されるパスワードがハッシュされていることを前提としています