在laravel Authtication Process中,我想加密users表中的email字段(我使用过Crypt :: encrypt())。这样做,登录过程失败。我必须在登录时验证加密的电子邮件。有人可以帮我吗?
如果我确实理解你的问题,解决它的一个好方法是使用装饰模式!由于Laravel提供了一种轻松创建中间件的方法,我们可以将它们用作装饰器。
你需要做的是添加一个名为encryptEmails的中间件,正如我们所知,中间件可以访问请求对象!我们现在需要做的是从请求中检索电子邮件值并通过加密来更改它。
当然,您必须在登录路线中包含此中间件。
使用此方法,您无需更改内置身份验证类的内容。
这是中间件的句柄函数的代码(我不确定加密电子邮件的类或方法):
public function handle($request, Closure $next)
{
$request->email = Crypt::encrypt($request->email)
return $next($request);
}
您可以查看此链接以获取有关Laravel中间件的更多信息:https://laravel.com/docs/5.7/middleware
在这种情况下,您应该允许用户使用用户名登录。 Override the username()
中的LoginController
方法:
public function username()
{
return 'username';
}
如果您仍想使用电子邮件进行身份验证,则需要加载所有用户,然后检查每个用户的解密电子邮件,如果您注册了许多用户,那么这不是一个好主意。
$users = User::all();
foreach ($users as $user) {
if ($request->email === decrypt($user->email) && \Hash::check($request->password, $user->password)) {
auth()->login($user); // Login the user if email and password are correct
break; // Exit from the foreach loop
}
}
你也可以chunk the data。
同样,此解决方案仅适用于少数注册用户。
我在LoginController
中使用了以下代码,并在Laravel 5.6中为我工作,
public function attemptLogin(Request $request) {
$users = User::all();
$isUserValidated=false;
$field = $request->username;
foreach ($users as $user) {
try { // required if the field is not encrypted
// login using username or email
if (($field === Crypt::decryptString($user->email) || $field === Crypt::decryptString($user->username)) && \Hash::check($request->password, $user->password)) {
$isUserValidated=true;
$this->guard()->login($user,false);
break; // Exit from the foreach loop
}
} catch (DecryptException $e) {
//
}
}
return $isUserValidated;
}
我认为能够加密电子邮件以进行登录非常重要。 Laravel的问题在于它总是使用不同的初始化向量。
若要解决此问题,您可以创建两个使用固定初始化向量的方法。然后,您不必遍历所有用户。您可以将请求中的电子邮件与数据库记录进行比较。
从模型中读取时,必须始终解密电子邮件。保存时,必须始终加密。如果使用唯一规则和电子邮件规则进行验证,则必须分两步验证用户数据。首先是规则电子邮件验证格式,然后加密传递的电子邮件,然后通过规则unqiue验证。
我希望我能帮助一点。
注意:这不是一个现成的解决方案,只是一个代码示例作为一个想法。如果您尝试此解决方案,则需要注意密码代理和密码重置。
/**
* Get a new initialization vector
* Store this initialization vector in your app-config (/config/app.php)
**/
function getNewIv() :string
{
return openssl_random_pseudo_bytes(16);
}
/** encrypt **/
function encryptEmail(string $email): string
{
$cipher = config('app.cipher', 'AES-256-CBC');
$key = config('app.key');
$iv= config('app.iv');
$encrypted = openssl_encrypt($email, $cipher, $key, 1, base64_decode($iv));
return base64_encode($encrypted);
}
/** decrypt **/
function decryptEmail(string $email): string
{
$data = base64_decode($decryptString);
$cipher = config('app.cipher', 'AES-256-CBC');
$key = config('app.key');
$iv= config('app.iv');
return openssl_decrypt($data, $cipher, $key, 1, base64_decode($iv));
}