问题
This is pretty standard login function and validation that works nicely. But I also want to check that the user is active. I have set up a column in my users table with 'active' set to either 0 or 1.
public function post_login()
{
$input = Input::all();
$rules = array(
'email' => 'required|email',
'password' => 'required',
);
$validation = Validator::make($input, $rules);
if ($validation->fails())
{
return Redirect::to_route('login_user')
->with_errors($validation->errors)->with_input();
}
$credentials = array(
'username' => $input['email'],
'password' => $input['password'],
);
if (Auth::attempt($credentials))
{
// Set remember me cookie if the user checks the box
$remember = Input::get('remember');
if ( !empty($remember) )
{
Auth::login(Auth::user()->id, true);
}
return Redirect::home();
} else {
return Redirect::to_route('login_user')
->with('login_errors', true);
}
}
I've tried something like this already:
$is_active = Auth::user()->active;
if (!$is_active == 1)
{
echo "Account not activated";
}
But this can only be used within the 'auth attempt' if statement and at that point the users credentials(email and pass) are already validated. So even if the users account if not active at this point they are already logged in.
I need a way to return validation to let them know they still need to activate their account and check if their account is set at the same time their email and pass are being checked.
回答1:
A better solution might be to create an Auth driver that extends the Eloquent Auth driver already in use and then override the attempt method.
Then change your auth config to use your driver.
Something like:
<?php
class Myauth extends Laravel\Auth\Drivers\Eloquent {
/**
* Attempt to log a user into the application.
*
* @param array $arguments
* @return void
*/
public function attempt($arguments = array())
{
$user = $this->model()->where(function($query) use($arguments)
{
$username = Config::get('auth.username');
$query->where($username, '=', $arguments['username']);
foreach(array_except($arguments, array('username', 'password', 'remember')) as $column => $val)
{
$query->where($column, '=', $val);
}
})->first();
// If the credentials match what is in the database we will just
// log the user into the application and remember them if asked.
$password = $arguments['password'];
$password_field = Config::get('auth.password', 'password');
if ( ! is_null($user) and Hash::check($password, $user->{$password_field}))
{
if ($user->active){
return $this->login($user->get_key(), array_get($arguments, 'remember'));
} else {
Session::flash('authentication', array('message' => 'You must activate your account before you can log in'));
}
}
return false;
}
}
?>
In your login screen, check for Session::get('authentication') and handle accordingly.
Alternatively, allow them to log in but don't let them access any pages other than one that offers a link to resend the activation email.
回答2:
Filters are the way to go. It's easy and clean to solve this problem, see my example below.
Route::filter('auth', function()
{
if (Auth::guest())
{
if (Request::ajax())
{
return Response::make('Unauthorized', 401);
}
else
{
return Redirect::guest('login');
}
}
else
{
// If the user is not active any more, immidiately log out.
if(Auth::check() && !Auth::user()->active)
{
Auth::logout();
return Redirect::to('/');
}
}
});
回答3:
Can't you use something like this:
if (Auth::once($credentials))
{
if(!Auth::user()->active) {
Auth::logout();
echo "Account not activated";
}
}
回答4:
Just make the active field one of the confirmations. You can do this:
$credentials = array(
'username' => $input['email'],
'password' => $input['password'],
'active' => 1
);
if (Auth::attempt($credentials))
{
// User is active and password was correct
}
If you want to specifically tell the user they are not active - you can follow it up with this:
if (Auth::validate(['username' => $input['email'], 'password' => $input['password'], 'active' => 0]))
{
return echo ('you are not active');
}
回答5:
This is what I do:
if (\Auth::attempt(['EmailWork' => $credentials['EmailWork'], 'password' => $credentials['Password']], $request->has('remember'))) {
if (\Auth::once(['EmailWork' => $credentials['EmailWork'], 'password' => $credentials['Password']])) {
if (!\Auth::user()->FlagActive == 'Active') {
\Auth::logout();
return redirect($this->loginPath())
->withInput($request->only('EmailWork', 'RememberToken'))
->withErrors([
'Active' => 'You are not activated!',
]);
}
}
return redirect('/');
}
return redirect($this->loginPath())
->withInput($request->only('EmailWork', 'RememberToken'))
->withErrors([
'EmailWork' => $this->getFailedLoginMessage(),
]);
来源:https://stackoverflow.com/questions/16750375/check-for-active-user-state-with-laravel