更新:
我尝试在我最近的一个项目中使用此代码,但它不再起作用了。原因是 HWIOAuthBundle 更新了几次,配置文件不一样。我将代码放在上面,并在 github 中登录了其他一些社交网络,您可以在HWIOAuthBundleByExample中找到。
我有一周的 symfony2 经验,在过去的几天里,这就是我自己的工作。今天找到了你的问题(当我还在研究的时候)。
我将根据哪些数据以及我是如何做到的,向您展示我必须做的事情。之后,我将尝试为您提供一些关键链接,希望您能够根据自己的需要进行建模。
我的应用需要 Facebook 登录和管理员角色。因为只会是几个管理员,所以我在认证的时候只需要几个Facebook ID,所以我将它们存储在一个yaml数组中。(见最后如何从数据库中加载它们)。
这是我所做的:
#/app/config.yml #the setup looks different (I need the picture and email credentials)
hwi_oauth:
# name of the firewall in which this bundle is active, this setting MUST be set
firewall_name: secured_area
resource_owners:
facebook:
type: facebook
client_id: %facebook_client_id%
client_secret: %facebook_client_secret%
scope: "email"
infos_url: "https://graph.facebook.com/me?fields=username,name,email,picture.type(square)"
paths:
email: email
profilepicture: picture.data.url
services: #here's where the magic happens
hwi_oauth.user.provider.entity:
class: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider
ib_user.oauth_user_provider:
class: Acme\DemoBundle\Provider\Provider
arguments: [@session, @doctrine, %admins%]
#app/security.yml
security:
providers:
my_custom_hwi_provider:
id: ib_user.oauth_user_provider
access_control:
- { path: ^/admin, roles: ROLE_SUPER_ADMIN }
#app/parameters.yml
parameters:
#...
facebook_client_id: ###
facebook_client_secret: ###
admins:
- "my.facebook.id"
#Acme\DemoBundle\Provider\Provider
<?php
namespace Acme\DemoBundle\Provider;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use Acme\DemoBundle\Entity\User;
use Acme\DemoBundle\Provider\OAuthUser;
class Provider extends OAuthUserProvider
{
protected $session, $doctrine, $admins;
public function __construct($session, $doctrine, $admins) {
$this->session = $session;
$this->doctrine = $doctrine;
$this->admins = $admins;
}
public function loadUserByUsername($username)
{
return new OAuthUser($username, $this->isUserAdmin($username)); //look at the class below
}
private function isUserAdmin($nickname)
{
return in_array($nickname, $this->admins);
}
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
//data from facebook response
$facebook_id = $response->getUsername();
$nickname = $response->getNickname();
$realname = $response->getRealName();
$email = $response->getEmail();
$avatar = $response->getProfilePicture();
//set data in session
$this->session->set('nickname', $nickname);
$this->session->set('realname', $realname);
$this->session->set('email', $email);
$this->session->set('avatar', $avatar);
//get user by fid
$qb = $this->doctrine->getManager()->createQueryBuilder();
$qb ->select('u.id')
->from('AcmeDemoBundle:User', 'u')
->where('u.fid = :fid')
->setParameter('fid', $facebook_id)
->setMaxResults(1);
$result = $qb->getQuery()->getResult();
//add to database if doesn't exists
if ( !count($result) ) {
$User = new User();
$User->setCreatedAt(new \DateTime());
$User->setNickname($nickname);
$User->setRealname($realname);
$User->setEmail($email);
$User->setAvatar($avatar);
$User->setFID($facebook_id);
$em = $this->doctrine->getManager();
$em->persist($User);
$id = $em->flush();
} else {
$id = $result[0]['id'];
}
//set id
$this->session->set('id', $id);
//@TODO: hmm : is admin
if ($this->isUserAdmin($nickname)) {
$this->session->set('is_admin', true);
}
//parent:: returned value
return $this->loadUserByUsername($response->getNickname());
}
public function supportsClass($class)
{
return $class === 'Acme\\DemoBundle\\Provider\\OAuthUser';
}
}
#Acme\DemoBundle\Provider\OAuthUser
<?php
namespace Acme\DemoBundle\Provider;
use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser as HWIOAuthUser;
class OAuthUser extends HWIOAuthUser{
private $isAdmin = false;
public function __construct($username, $isAdmin = false)
{
parent::__construct($username);
$this->isAdmin = $isAdmin;
}
public function getRoles()
{
$roles = array('ROLE_USER', 'ROLE_OAUTH_USER');
if ($this->isAdmin) {
array_push($roles, 'ROLE_SUPER_ADMIN');
}
return $roles;
}
}
因此,您几乎可以看到,当 facebook 登录响应出现时,我会进行数据库检查(基于 facebook 图 ID),并在需要时添加它。另外,我在会话中设置了一些东西(你不需要这个),之后我还必须返回一个 HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser 对象(这是 sf2 获得它的角色的地方)。所以我扩展了它(通过这种方式我可以访问 $isAdmin)。正如您所说,您需要每个用户的角色,您还必须编辑它们。为此,您可以使用 ManyToMany 关系实现 getRoles() (通过构造函数访问学说 entityManager)。你可以在这里看到应用:http: //symfony.com/doc/current/cookbook/security/entity_provider.html#managing-roles-in-the-database。
正如我所说,您必须对其进行大量调整(我唯一的应用程序是仅限 facebook 登录并具有类似安全访问的 in_memory),但我希望自己在开始时有这样的代码。所以我真的希望这对你有帮助。发布您的问题,如果有的话。