事实上,通过rest使用symfony2身份验证wsse,我采用phonegap开发我的客户端,我已经开发了一个在服务器部分生成令牌的算法,但是每次我必须返回密码,这很危险,所以最好的解决方案是只发送在客户端生成的令牌,一旦使用服务器,它就会被破坏,我的问题是如何在客户端(JavaScript)开发一个类似于 symfony2 的“encodePassword”的算法。
这是在 symfony2 中生成密码的类
class MessageDigestPasswordEncoder extends BasePasswordEncoder{
private $algorithm;
private $encodeHashAsBase64;
/**
* Constructor.
*
* @param string $algorithm The digest algorithm to use
* @param Boolean $encodeHashAsBase64 Whether to base64 encode the password hash
* @param integer $iterations The number of iterations to use to stretch the password hash
*/
public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000)
{
$this->algorithm = $algorithm;
$this->encodeHashAsBase64 = $encodeHashAsBase64;
$this->iterations = $iterations;
}
/**
* {@inheritdoc}
*/
public function encodePassword($raw, $salt)
{
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
$salted = $this->mergePasswordAndSalt($raw, $salt);
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; $i++) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
/**
* {@inheritdoc}
*/
public function isPasswordValid($encoded, $raw, $salt)
{
return $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
}
这 是我在客户端生成令牌的方法
public function postTokenCreateAction()
{
$view = FOSView::create();
$request = $this->getRequest();
$username = $request->get('_username');
$password = $request->get('_password');
$um = $this->get('fos_user.user_manager');
$user = $um->findUserByUsernameOrEmail($username);
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($user);
$password = $encoder->encodePassword($password, $user->getSalt());
if (!$user instanceof User) {
throw new AccessDeniedException("Wrong user");
}
$created = date('c');
$nonce = substr(md5(uniqid('nonce_', true)), 0, 16);
$nonceHigh = base64_encode($nonce);
$passwordDigest = base64_encode(sha1($nonce . $created . $password, true));
$header = "UsernameToken Username=\"{$username}\", PasswordDigest=\"{$passwordDigest}\", Nonce=\"{$nonceHigh}\", Created=\"{$created}\"";
$view->setHeader("Authorization", 'WSSE profile="UsernameToken"');
$view->setHeader("X-WSSE", "UsernameToken Username=\"{$username}\", PasswordDigest=\"{$passwordDigest}\", Nonce=\"{$nonceHigh}\", Created=\"{$created}\"");
$data = array('WSSE' => $header);
$view->setStatusCode(200)->setData($data);
return $view;
}