symfony - Symfony2: How to login using OAuth (HWIOAuthBundle) + custom roles (by default and loaded from DB) -
note: questions @ end of text explain in detail context better understanding.
i'm developing symfony2 application consisting of 3 modules:
- module students -> needs role role_student
- module teachers -> needs role role_teacher
- module administrators -> needs role role_admin
the role hierarchy follows:
- role_teacher: [role_student]
- role_admin: [role_teacher]
therefore:
a student (with role_student role) can access pages of his/her module, example:
a teacher (with role_teacher role) can access pages of students' module , pages of teachers' module, such as:
an administrator (with role_admin role) can access pages of students' module, pages of teachers' module , admin backend.
the system uses oauth authenticate students , teachers through twitter, using bundle hwioauthbundle (using oauthuserprovider user provider provides bundle).
i've achieved authenticate users but, by default, users automatically authenticated with following roles: [role_user, role_oauth_user]
so here have done. below, i'm going explain want app don't know way:
steps login using oauth:
a user logs in system , automatically:
if user not exist in database:
- save nickname in users table of database.
- save role role_student (this role default me) in users table of database.
- authenticate in system using oauth using role_student role.if user exists in database:
- check role has associated user in database.
- authenticate user in system using oauth using role associated in database (i.e.: role_student or role_teacher).
the administrator (from administration backend) can see list of nicknames (used twitter saved in database) , assigned roles each nickname. administrator should able change role of users between role_student , role_teacher.
the questions:
how can authenticate user via oauth (hwioauthbundle) role want default (role_student explained above)?
if nickname exists in database role associated (role_student or role_teacher), how can authenticate user via oauth (hwioauthbundle) using role loaded database?
i've been reading lot subject i'm new symfony2 , don't know best , easiest way solve it.
thank in advance!
ps: if have questions or doubts anything, i'll glad explain best possible.
update:
i tried using code in 1 of recent projects , didn't work anymore. reason hwioauthbundle has updated few times , config files not same. put code above login few other social networks in github can find @ hwioauthbundlebyexample.
i have week experience symfony2 , in past days that's working myself. found question today (when still researching).
i'm gonna present had do, based on data, , how did it. after that, i'll try giving key links , hope you'll manage modelate needs.
my app needs facebook login , admin role. because few administrators, need few facebook ids when authentificating, store them in yaml array. (see @ end how can load them database).
here's did:
#/app/config.yml #the setup looks different (i need picture , email credentials) hwi_oauth: # name of firewall in bundle active, setting must 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 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 @ class below } private function isuseradmin($nickname) { return in_array($nickname, $this->admins); } public function loaduserbyoauthuserresponse(userresponseinterface $response) { //data 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 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 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 : 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 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; } }
so can pretty see when facebook login response comes, database checks (based on facebook graph id), , add if needed. also, set things in sessions (you won't need this), , after must return hwi\bundle\oauthbundle\security\core\user\oauthuser object (this sf2 gets it's roles). extend (in way have acces $isadmin). said, need roles each user , must edit them. that, can implement getroles() manytomany relationship (give access doctrine entitymanager via constructor). can see applied here: http://symfony.com/doc/current/cookbook/security/entity_provider.html#managing-roles-in-the-database .
as said, must tweak lot (my app facebook-only login , in_memory security access), wish myself had code when started. hope hels you. post questions, if any.
Comments
Post a Comment