您的位置:首页 > 大数据 > 人工智能

symfony开源框架学习之sfGuardplugin简单剖析

2011-04-11 00:54 176 查看
最近接触了symfony这个开源框架,MVC的架构确实使人耳目一新,本打算潜心研究一番,无奈项目进度催人,只好边用边学了,所以不足之处还望见谅,也希望高手能指点一二,不胜感激。

 

用symfony的估计都会安装sfGuardplugin这个插件,配置完后整个站点的认证几乎不用操心了,它能提供全方位保护。但是默认方式就是提供个登陆框,功能很单一(我也没仔细看,可能还有其他可视界面)。我现在的实际项目是要求编写站点API,来响应不同客户端请求。那么最基本的登陆注册模块就需要涉及到sfGuardplugin了,因为安装插件时在数据库里自动生成了sf_guard_user表,里面有username和password,且password用sha1加密。下面就来说说如何结合这个插件来自定义登陆注册模块。

 

1、关于sfGuard的数据库

sfGuard默认只提供username和password,那么要想添加其他的表项就只有两种方式了,改写原表或使用foreignTable。原表路径位于sfGuardPlugin/config/schema.yml,其中最主要的是sf_guard_user这一项,可以自己添加email,birth,nickname.....默认的加密算法也可以改为md5。当然基于分表原理,我更倾向于使用foreigenTable,我们可以新建一张userInfo表,添加外键指向id就行了。另外要注意的是作者每张表都利用_attributes参数重新命名了,所以我们在实际代码引用中会用到sfGuardUserPeer,而不是sf_guard_userPeer。

 

2、深入sfGuard

首先介绍插件中几个重要的文件:

modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php 着重注意executeSignin()和executeSignout()函数,可以在这儿通过修改setFlash设置登录登出提示

 

lib/model/sfGuardUser.php<------lib/model/plugin/PluginsfGuardUser.php 其中的setPassword($password),checkPassword($password)可以自动对原始密码加密以及校验

public function setPassword($password)
{
if (!$password && 0 == strlen($password))
{
return;
}
if (!$salt = $this->getSalt())
{
$salt = md5(rand(100000, 999999).$this->getUsername());
$this->setSalt($salt);
}
$algorithm = sfConfig::get('app_sf_guard_plugin_algorithm_callable', 'sha1');
$algorithmAsStr = is_array($algorithm) ? $algorithm[0].'::'.$algorithm[1] : $algorithm;
if (!is_callable($algorithm))
{
throw new sfException(sprintf('The algorithm callable "%s" is not callable.', $algorithmAsStr));
}
$this->setAlgorithm($algorithmAsStr);
parent::setPassword(call_user_func_array($algorithm, array($salt.$password)));
}
public function checkPassword($password)
{
try
{
$profile = $this->getProfile();
}
catch (Exception $e)
{
$profile = null;
}
if (!is_null($profile) && method_exists($profile, 'checkPassword'))
{
return $profile->checkPassword($this->getUsername(), $password, $this);
}
else if ($callable = sfConfig::get('app_sf_guard_plugin_check_password_callable'))
{
return call_user_func_array($callable, array($this->getUsername(), $password, $this));
}
else
{
return $this->checkPasswordByGuard($password);
}
}
 

 

lib/model/sfGuardUserPeer.php<------lib/model/plugin/PluginsfGuardUserPeer.php retrieveByUsername($username)检索$username并返回user对象,通过这个函数我们也可以举一反三写出retrieveByNickname, retrieveByEmail等等。

 

public static function retrieveByUsername($username, $isActive = true)
{
$c = new Criteria();
$c->add(self::USERNAME, $username);
$c->add(self::IS_ACTIVE, $isActive);
return self::doSelectOne($c);
}
 

lib/task/sfGuardCreateUserTask.class.php 从名字里就能知道这个是来创建新用户的,其中的execute()就是这个功能

protected function execute($arguments = array(), $options = array())
{
$databaseManager = new sfDatabaseManager($this->configuration);
$user = new sfGuardUser();
$user->setUsername($arguments['username']);
$user->setPassword($arguments['password']);
$user->save();
$this->logSection('guard', sprintf('Create user "%s"', $arguments['username']));
}
 

别看插件包里文件很多,常用的也就这几个,其他的组管理,权限管理现在没用到,也没有发言权了。

 

3. 实践代码

通过对sfGuardplugin源码的学习,我也更近一步的理解了symfony的运行机制,帮助很大。下面谈谈怎样在实际项目中应用

场景一:客户端通过post方式传递username和password,服务端处理请求并返回结果。代码片段如下:

//获取username和password
$name=$request->getParameter( 'username');
$pswd=$request->getParameter( 'password');
//检查username是否在数据库中,这里可以通过var_dump()看看$name的结构
$name=sfGuardUserPeer::retrieveByUsername( $name);
//近一步检查密码,这里函数会自动进行sha1或md5的检验,保证了安全性
if(!$name || !$name-> checkPassword( $pswd)){
return $this-> renderText('fail');
}
else{
return $this->renderText('ok');
}


场景二:客户端通过post方式提交username,password,email进行注册,服务端处理请求并返回结果。代码片段如下:

$name=$request->getParameter( 'username');
$pswd=$request->getParameter( 'password');
$email=$request-> getParameter( 'email');
//先保存username和password
$user=new sfGuardUser() ;
$user-> setUsername( $name);
$user-> setPassword( $pswd);
$user-> setCreatedAt( time( )) ;
$user-> save( ) ;
//检查是否已有同名用户
if(!sfGuardUserPeer::retrieveByUsername( $name)) {
//检查email是否已被注册
if(UserinfoPeer::retrieveByEmail( $email))
return $this-> renderText( 'email registered!');
//得到sfGuardUser表的外键id
$getId=BasesfGuardUserPeer::doInsert($user);
//将email存储到userinfo表中,并关联外键
$uinfo=new userinfo( ) ;
$uinfo-> setUemail($email) ;
$uinfo-> setSid($getId);
$uinfo-> save( );
re
85e3
turn $this->renderText('ok');
}
else{
return $this-> renderText('fail' );
}


created by Ethan4cs 2011-04-11
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息