【发布时间】:2015-04-15 08:19:41
【问题描述】:
我在后端应用程序中使用 laravel bcrypt 身份验证,但客户端要求纯密码身份验证,以便他可以以管理员身份查看每个用户的密码。我的整个应用程序逻辑都基于 laravel 内置身份验证方法和 bcrypt 散列。如何将其替换为使用存储在数据库中而不是存储哈希的普通密码 mach 进行身份验证?
【问题讨论】:
标签: laravel-5
我在后端应用程序中使用 laravel bcrypt 身份验证,但客户端要求纯密码身份验证,以便他可以以管理员身份查看每个用户的密码。我的整个应用程序逻辑都基于 laravel 内置身份验证方法和 bcrypt 散列。如何将其替换为使用存储在数据库中而不是存储哈希的普通密码 mach 进行身份验证?
【问题讨论】:
标签: laravel-5
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
public function __construct()
{
$this->middleware('guest', ['except' => ['getLogout', 'getLogin']]);
}
public function postLogin()
{
$data = \Request::all();
$rules = [
'email' => 'required|email|max:255|exists:users',
'password' => 'required|exists:users'
];
$validator = \Validator::make($data, $rules);
if ($validator->fails()) {
//login data not exist in db
return redirect('/login')->withErrors($validator)->withInput();
} else {
$email = Request::input('email');
$pass = Request::input('password');
//in my table users, status must be 1 to login into app
$matchWhere = ['login' => $email, 'password' => $pass, 'status' => 1];
$count = \App\User::where($matchWhere)->count();
if ($count == 1) {
$user = \App\User::where($matchWhere)->get();
$user_id = null;
foreach ($user as $u) {
$user_id = intval($u->id);
}
Auth::loginUsingId($user_id);
//start session and save data
return redirect()->intended('/');
} else {
//not status 1 or active
$validator->errors()->add('Unauthorized', 'Not accepted in community yet');
return redirect('/login')->withErrors($validator)->withInput();
}
}
}
public function getLogin()
{
//fix for infinite loop in my app
if (Auth::check()) {
return redirect()->intended('/');
} else {
return view('auth.login');
}
}
public function getLogout()
{
Auth::logout();
return redirect()->intended('/login');
}
}
【讨论】:
如果你现在使用 Laravel 5^,你可以通过搜索 Illuminate/Auth/EloquentUserProvider 类并在其中做一些小的调整来做到这一点。
例如找到公共函数retrieveByCredentials() 和validateCredentials()。在第二个函数中,您可以看到 laravel 正在检查要输入 Auth::attempt() 方法的散列密码。只需将其更改为普通检查即可。
public function retrieveByCredentials(array $credentials)
{
if (empty($credentials)) {
return;
}
// First we will add each credential element to the query as a where clause.
// Then we can execute the query and, if we found a user, return it in a
// Eloquent User "model" that will be utilized by the Guard instances.
$query = $this->createModel()->newQuery();
foreach ($credentials as $key => $value) {
if (! Str::contains($key, 'password')) {
$query->where($key, $value);
}
}
return $query->first();
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserContract $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
将 $this->hasher->check 更改为普通检查,您将完成。 :)
【讨论】:
在 laravel 4 中你可以重写 HASH 模块。这个stackoverflow thread 解释了如何使用 SHA1 而不是 bycrypt [检查接受的答案和 cmets]。
您可以使用此处介绍的方法,无需散列即可保存密码。
【讨论】:
嗯,这确实会损害您客户的网站安全。 根本不建议在数据库中存储纯密码。如果有人获得了对数据库的访问权,他/她的网站将非常容易受到攻击,任何拥有数据库副本的人都可以轻松访问所有类型的帐户。我坚持认为您应该创建一个重置/更改密码功能,而不是在数据库中存储普通密码。 无论如何,您可以使用
获得纯密码$password = Input::get('password');
我猜你可以用
验证用户if (Auth::attempt(array('password' => $password)))
{
return Redirect::route('home');
}
【讨论】:
哇,这些都好复杂,就这么简单。
if ($user = User::where('email', request()->email)->where('password', request()->password)->first()) {
Auth::login($user);
return redirect()->to('/');
}
虽然我同意在生产环境中您不应该这样做。但是对于某些应用程序,如果用户知道密码以纯文本形式存储,我可以看到它可能没问题。
【讨论】: