1) User clicks 'Login with facebook'
2) Redirect the user to http://www.facebook.com/dialog/oauth?client_id=xx开发者_StackOverflow社区&redirect_url=xxx&etcetc
3) User clicks allow, returns to our site.
4) We are able to fetch the user's name, email, and other settings that we have permission for, and using that we are able to create an account for him on our website with a random password.
5) Next time user clicks this button, if we already have an account for him on our site (using email address to compare), we simply auto login him in step 4
Absolutely use the SDK. The advantage being that it's a library that's tested and used in the wild. Never rebuild the wheel when you don't have to (you'll find that you get more done ;)).
What I ended up doing in CI was to add the Facebook PHP SDK to my libraries directory and change the __construct
function of the Facebook
class to be:
public function __construct()
{
$ci =& get_instance();
$this->setAppId($ci->config->item('fb_appId'));
$this->setApiSecret($ci->config->item('fb_secret'));
$this->setCookieSupport($ci->config->item('fb_cookie'));
$this->setBaseDomain($ci->config->item('fb_domain'));
$this->setFileUploadSupport($ci->config->item('fb_upload'));
}
Then,
- I added all of the above key/value pairs to config/config.php
- Added the facebook library to the autoloads list
Once that was done, I could access the FB API from anywhere in my app through $this->facebook
.
Having said all that, this was all pre-2.0, so I'm not entirely sure what the changes would be if needed (I'm using Yii now, which is mainly why I don't know if changes are required :)).
Hope that helps.
Edit:
As requested, I ended up adding a UserModel
class (extending Model
). I have support for multiple login providers, so I won't post the whole thing. But, this is the gist of it:
class UserModel extends Model
{
private $m_user;
public function UserModel()
{
parent::Model();
$this->m_user = null;
$session = $this->facebook->getSession();
if($session)
{
if($this->facebook->api('/me') != null)
{
$this->m_user = $this->facebook->api('/me');
}
}
}
public function getUser()
{
return $this->m_user;
}
public function isLoggedIn()
{
return $this->getUser() != null;
}
// returns either the login or logout url for the given provider, relative to the
// state that the current user object is in
public function getActionUrl()
{
if($this->isLoggedIn())
{
return $this->facebook->getLogouturl();
}
else
{
return $this->facebook->getLoginUrl(array('next'=>currentUrl(), 'cancel'=>currentUrl(), 'req_perms'=>null, 'display'=>'popup'));
}
}
}
Then, I added a login widget, which simply contains this:
<div id="header-login">
<!-- todo: this won't work with konqueror atm (fb script bugs) - check 'em out later -->
<?php if(!$user->isLoggedIn()): ?>
<fb:login-button perms="email"><?php echo lang('fb_login'); ?></fb:login-button>
<?php else: ?>
<a onclick="FB.logout();" class="fb_button fb_button_medium"><span class="fb_button_text">Logout</span></a>
<?php endif; ?>
</div>
Second edit:
Sorry, it's been a while since I wrote that, so I had to go back and figure out exactly how it was implemented :P After a quick grep, I found that I'm not actually using getActionUrl
anywhere. I had added some client script to listen to FB login/logout events:
google.setOnLoadCallback(on_load);
google.load("jquery", "1.4.4");
window.fbAsyncInit = function() {
FB.init({appId: '[id]', status: true, cookie: true, xfbml: true});
FB.Event.subscribe('auth.login', on_fb_login);
FB.Event.subscribe('auth.logout', on_fb_logout);
};
function on_load()
{
// force all anchors with the rel tag "ext" to open in an external window
// (replaces target= functionality)
$('a[rel="ext"]').click(function(){
window.open(this.href);
return false;
});
}
function on_fb_login()
{
location.reload();
}
function on_fb_logout()
{
location.reload();
}
精彩评论