我正在使用Sentinel构建一个laravel应用程序,该应用程序基于Yii中的旧系统代码。
目的是能够与旧用户/旧数据库一起登录新系统。
我首先必须解决模型问题:
自定义模型和字段与Sentinel/Laravel
现在,一切都好了。
我有最后一个问题,它似乎是从不同的方式散列密码。
当我在Yii中检查哈希方法时,我可以发现它使用Blowfish算法:
/**
* CPasswordHelper provides a simple API for secure password hashing and verification.
*
* CPasswordHelper uses the Blowfish hash algorithm available in many PHP runtime
* environments through the PHP {@link http://php.net/manual/en/function.crypt.php crypt()}
* built-in function. As of Dec 2012 it is the strongest algorithm available in PHP
* and the only algorithm without some security concerns surrounding it. For this reason,
* CPasswordHelper fails to initialize when run in and environment that does not have
* crypt() and its Blowfish option. Systems with the option include:
* (1) Most *nix systems since PHP 4 (the algorithm is part of the library function crypt(3));
* (2) All PHP systems since 5.3.0; (3) All PHP systems with the
* {@link http://www.hardened-php.net/suhosin/ Suhosin patch}.
* For more information about password hashing, crypt() and Blowfish, please read
* the Yii Wiki article
* {@link http://www.yiiframework.com/wiki/425/use-crypt-for-password-storage/ Use crypt() for password storage}.
* and the
* PHP RFC {@link http://wiki.php.net/rfc/password_hash Adding simple password hashing API}.
*
* CPasswordHelper throws an exception if the Blowfish hash algorithm is not
* available in the runtime PHP's crypt() function. It can be used as follows
*
另一方面,Sentinel管理几种哈希方法:
Native hasher
Bcrypt hasher
Callback hasher
Whirlpool hasher
SHA256 hasher
所以,我猜常见的方法是bcrypt,在我的Laravel模型中,我做到了:
class Administrador extends EloquentUser {
protected $table = 'administrador';
protected $fillable = [];
protected $primaryKey = 'administradorid';
protected $loginNames = ['correo'];
protected $guarded = ['administradorid'];
protected $hidden = ['contrasena', 'remember_token'];
use SoftDeletes;
protected $dates = ['deleted_at'];
/**
* Set the Sentry User Model Hasher to be the same as the configured Sentry Hasher
*/
public static function boot()
{
parent::boot();
Sentinel::setHasher(new BcryptHasher);
}
}
所以说真的,我真的不知道该怎么解决…
此时您可以做的是创建CartalystSentinalHashingHasherInterface
的实现,例如:
use CartalystSentinelHashingHasherInterface;
class CombinedHasher implements HasherInterface
{
/**
* @var HasherInterface
*/
private $primary;
/**
* @var HasherInterface
*/
private $fallback;
/**
* @param HasherInterface $primary
* @param HasherInterface $fallback
*/
public function __construct(HasherInterface $primary, HasherInterface $fallback)
{
$this->primary = $primary;
$this->fallback = $fallback;
}
/**
* Hash the given value.
*
* @param string $value
* @return string
* @throws RuntimeException
*/
public function hash($value)
{
return $this->primary->hash($value);
}
/**
* Checks the string against the hashed value.
*
* @param string $value
* @param string $hashedValue
* @return bool
*/
public function check($value, $hashedValue)
{
if ($this->primary->check($value, $hashedValue)) {
return true;
}
return $this->fallback->check($value, $hashedValue);
}
}
正如您所看到的,它需要HasherInterface
的两个实例。因此,在这种情况下,您将首先注入您希望使用的新实现,然后创建接口的实现,该接口实现Yii正在使用的哈希算法。
在检查散列时,它将首先使用新的散列算法。如果返回false
,它也将使用回退(Yii算法)进行检查。要创建哈希,它将只使用新的哈希算法。(您可能想为了开发而更改此项,但无论如何都不应该使用生产数据库进行开发。)
所以你接下来要做的是创建一个HasherInterface
的实现,它将使用Yii正在使用的哈希算法:
use CartalystSentinelHashingHasherInterface;
class YiiHasher implements HasherInterface
{
/**
* Hash the given value.
*
* @param string $value
* @return string
* @throws RuntimeException
*/
public function hash($value)
{
// You'll have to implement this
return yiiHasher($value);
}
/**
* Checks the string against the hashed value.
*
* @param string $value
* @param string $hashedValue
* @return bool
*/
public function check($value, $hashedValue)
{
// You'll have to implement this
return yiiHashChecker($value, $hashedValue);
}
}
你必须检查Yii是否有这样的软件包,或者你必须检查他们的源代码,看看它是如何工作的。
所以要使用它,您需要创建一个CombinedHasher
的实例,如下所示:
use CartalystSentinelHashingBcryptHasher;
use NamespaceForYourYiiHasher;
$primary = new BcryptHasher();
$fallback = new YiiHasher();
$hasher = new CombinedHasher($primary, $fallback);
更新1:文档中的额外信息
在实际阅读了他们的文档后,我注意到他们还提供了CallbackHasher
,这可能需要较少的设置工作:https://cartalyst.com/manual/sentinel/2.0#callback-散列
他们还建议使用NativeHasher
而不是BcryptHasher
:https://cartalyst.com/manual/sentinel/2.0#native-散列
更新2:在哪里设置
例如,您可以在app/Hashing
中创建它们。然后,您必须确保它们具有名称空间AppHashing
。
要进行设置,您可以使用位于app/Providers/AppServiceProvider.php
中的AppServiceProvider
。
// Import the classes on the top
use AppHashingCombinedHasher;
use AppHashingYiiHasher;
use CartalystSentinelHashingNativeHasher;
// In the AppServiceProvider class itself
public function boot()
{
$hasher = $this->app['CartalystSentinelHashingHasherInterface'];
Sentinel::setHasher($hasher);
}
public function register()
{
$this->app->singleton('CartalystSentinelHashingHasherInterface', function($app) {
$primary = new NativeHasher();
$secondary = new YiiHasher();
return new CombinedHasher($primary, $secondary);
});
}