{"id":33,"date":"2012-03-16T12:49:19","date_gmt":"2012-03-16T12:49:19","guid":{"rendered":"http:\/\/blogs.law.harvard.edu\/acts\/?p=33"},"modified":"2012-04-09T09:23:59","modified_gmt":"2012-04-09T14:23:59","slug":"using-facebook-authentication-with-yii-php","status":"publish","type":"post","link":"https:\/\/archive.blogs.harvard.edu\/acts\/2012\/03\/16\/using-facebook-authentication-with-yii-php\/","title":{"rendered":"Using Facebook authentication with Yii (PHP)"},"content":{"rendered":"<p>Note: There many ways to implement this, but this seemed to make the most sense to me at the time.<\/p>\n<p>A login can either come from someone clicking a login link and being sent to a login page or we can force the login and not allow guests. \u00a0The login\/logout button is easy enough, just modify the distributed site controller&#8217;s login and logout &#8220;action&#8221; methods. \u00a0In order to force the login, the best wat to do this is to implement a behavior. \u00a0<a title=\"Larry Ullman's forcing login\" href=\"http:\/\/www.larryullman.com\/2010\/07\/20\/forcing-login-for-all-pages-in-yii\/\">Please see Larry Ullman&#8217;s blog for more information on that.<\/a><\/p>\n<p>Then we get to the IdentityFactory. \u00a0Yii has a nice configuration system in place for its components, so I did some Identity components extending the standard Yii UserIdentity that was included with the Yii distribution. I have the login entry point call on the identity factory which checks a param in the config and returns an instance of the appropriate object.<\/p>\n<p>These objects are where all authentication type specifics happen. \u00a0Lets take a look at a simple flow diagram:<\/p>\n<p><a href=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2012\/03\/Yii_Facebook_auth.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-38\" src=\"http:\/\/blogs.law.harvard.edu\/acts\/files\/2012\/03\/Yii_Facebook_auth-251x300.jpg\" alt=\"Facebook auth flow\" width=\"251\" height=\"300\" srcset=\"https:\/\/archive.blogs.harvard.edu\/acts\/files\/2012\/03\/Yii_Facebook_auth-251x300.jpg 251w, https:\/\/archive.blogs.harvard.edu\/acts\/files\/2012\/03\/Yii_Facebook_auth.jpg 388w\" sizes=\"auto, (max-width: 251px) 100vw, 251px\" \/><\/a><\/p>\n<p>So the IdentityFactory chooses which identity we&#8217;re using based on the config. \u00a0It will send the request over to the FacebookIdentity, which gets all the info needed for the UserIdentity class to query the database, update information there, and then set the user session.<\/p>\n<p>The more interesting part is the connection between FacebookIdentity and the Facebook SDK. \u00a0For this I made use of a Yii extension. \u00a0I used <a title=\"yii-facebook-opengraph\" href=\"http:\/\/www.yiiframework.com\/extension\/facebook-opengraph\/\">yii-facebook-opengraph<\/a>, which, while not the most mature of facebook connect extensions, is the most actively developed and the closest to functional. \u00a0(Last year Facebook made a huge change to their SDK which is not at all backwards compatible so they broke most extensions that exist and most developers did not make updates to their extensions.) \u00a0This extension only needed one method added to help deal with the <a title=\"Problems with the Facebook PHP SDK\" href=\"http:\/\/blogs.law.harvard.edu\/acts\/2012\/03\/15\/problems-with-the-facebook-php-sdk\/\">Facebook problem with access tokens<\/a>.<\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n\r\n\/\/ had to add this function to deal with php&#039;s poor handling of expired access tokens\r\npublic function setAccessToken($access_token){\r\nreturn $this-&gt;_getFacebook()-&gt;setAccessToken($access_token);\r\n}\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Note: There many ways to implement this, but this seemed to make the most sense to me at the time. A login can either come from someone clicking a login link and being sent to a login page or we can force the login and not allow guests. \u00a0The login\/logout button is easy enough, just [&hellip;]<\/p>\n","protected":false},"author":4571,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[63924,3163,63928,63937],"tags":[5741,981,63936,63930,63943],"class_list":["post-33","post","type-post","status-publish","format-standard","hentry","category-atg","category-php","category-quizmo-atg","category-yii","tag-authentication","tag-facebook","tag-facebook-sdk","tag-php-2","tag-yii-2"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/33","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/users\/4571"}],"replies":[{"embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/comments?post=33"}],"version-history":[{"count":9,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/33\/revisions"}],"predecessor-version":[{"id":43,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/posts\/33\/revisions\/43"}],"wp:attachment":[{"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/media?parent=33"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/categories?post=33"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/archive.blogs.harvard.edu\/acts\/wp-json\/wp\/v2\/tags?post=33"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}