http://developers.facebook.com/docs/plugins/registration/

Introduction

Registrationプラグインを使うと、ユーザは自分のFacebookアカウントを使ってあなたのサイトにサインアップできるようになります。このプラグインはiframeを使うので簡単に導入できます。ユーザがFacebookにログインしていれば、登録用の入力フォームはユーザの情報で補完されます。

Registrationプラグインは、Facebook APIでは取得できない追加情報(例えばお気に入りの映画)の入力にも柔軟に対応します。Facebookアカウントを持っていないユーザや、ログイン中の自分のFacebookアカウントを使いたくないと言うユーザに対応することも可能です。これにより、二通りのログイン状態を準備する必要が無くなります。

Example

<iframe src="http://www.facebook.com/plugins/registration.php?
             client_id=113869198637480&
             redirect_uri=http%3A%2F%2Ffacebook-docs.oklahome.net%2F&
             fields=name,birthday,gender,location,email"
        scrolling="auto"
        frameborder="no"
        style="border:none"
        allowTransparency="true"
        width="100%"
        height="330">
</iframe>

Attributes

AttributeDescription
client_idアプリケーションID
redirect_urisigned_requestを扱うURI(リダイレクト先)。設定したSite URLで始まるURIでなくてはなりません。
fieldsカンマ区切りのNamed Fieldsのリスト、もしくはJSON形式のCustom Fields
fb_onlyオプション(boolean)。Facebookプロフィールと紐づけた場合のみの登録を許します。独自の登録システムを持たない場合に使ってください。デフォルトはfalse。
widthオプション(int)iframeの横幅をピクセル指定。520よりも小さい場合は、小さいレイアウトでレンダリングします。
border_colorオプション。プラグインのボーダー色。

Named Fields

フォームに表示したい順に並べて指定してください。nameフィールドは常に最初に来ていなくてはなりません。
Field typeDescription
nameユーザのフルネーム
birthdaymm/dd/yyyy形式の誕生日
emailユーザのemailアドレス(ユーザがFacebookアカウントで登録処理する場合は、認証済みのemailアドレス)
gender性別
locationユーザの現住所(都市)の名前とID
password新規のパスワード(ユーザのFacebookアカウントのではありません)
captcha機械による登録処理を止める為のテスト

上記よりはマイナーな項目
Field typeDescription
first_nameユーザのファーストネーム。view=not_prefilled指定の際に便利です。
last_nameユーザのラストネーム

Custom Fields

Facebookで提供されない情報を求めることも可能です。その場合はfieldsアトリビュートに対して、CSVではなく、JSON形式の文字列を指定します。下記のサンプルを見てください。
上記の場合、fieldsには下記の指定がしてあります。
[
 {'name':'name'},
 {'name':'email'},
 {'name':'location'},
 {'name':'gender'},
 {'name':'birthday'},
 {'name':'password',   'view':'not_prefilled'},
 {'name':'like',       'description':'Do you like this plugin?', 'type':'checkbox',  'default':'checked'},
 {'name':'phone',      'description':'Phone Number',             'type':'text'},
 {'name':'anniversary','description':'Anniversary',              'type':'date'},
 {'name':'captain',   
'description':'Best Captain',             'type':'select',   
'options':{'P':'Jean-Luc Picard','K':'James T. Kirk'}},
 {'name':'force',     
'description':'Which side?',              'type':'select',   
'options':{'jedi':'Jedi','sith':'Sith'}, 'default':'sith'},
 {'name':'live',      
'description':'Best Place to Live',       'type':'typeahead',
'categories':['city','country','state_province']},
 {'name':'captcha'}
]
fieldsにはJSONの配列を渡します。ビルトインのフィールドはnameフィールドしか持っていません。
カスタムフィールドは下記を持ちます。

NameDescription
nameHTMLのinputnameに指定される。signed_requestをデコードした時に、アトリビュートの名前になります。
descriptionユーザに表示されるラベル
typeフィールドタイプ。text/date/select/checkbox/typeheadがサポートされています。
viewいつこのフィールドを表示するか。prefilledとnot_prefilledの二種類。prefilledはユーザは自分のFacebookアカ ウントを使って登録処理する場合で、not_prefilledはFacebookアカウントを使わずに登録処理する場合。このパラメータは、 Facebookアカウントを使わずに登録するユーザに対して、パスワードのみ入力させる時などに便利です。デフォルトでは、どちらの場合でも表示されます。
アトリビュートによっては、特定のタイプのみしか使えないものもあります。
NameDescription
optionsselectのみ
categoriestypeheadのみ。Open Graphプロトコルのtypeの配列がこのフィールドには有効
defaultselect/checkboxのみ。Select onを表示する代わりに、デフォルトで選択させるキーを指定。デフォルトでcheckboxをチェックさせるには、checkedという語を指定
カスタムフィールドを指定するにはより高度な機能もあり、クライアントサイドのバリデーションや非同期のバリデーション、Facebookへ値を渡したくない場合のno_submit機能などがあります。

XFBML

JavaScript SDKと一緒に使うXFBMLも提供されています。それを使う場合、サイズの変化に応じてiframeもリサイズされます。
<div id="fb-root"></div>
<script src="http://connect.facebook.net/en_US/all.js#appId={YOUR_APP_ID}&xfbml=1"></script>

<fb:registration
  fields="name,birthday,gender,location,email"
  redirect-uri="http://developers.facebook.com/tools/echo/"
  width="530">
</fb:registration>

ユーザにログインさせたり登録させる時には、XFBMLボタンが便利です。
<fb:login-button registration-url="http://developers.facebook.com/docs/plugins/registration" />
Facebookからログアウトした状態でユーザがサイトに訪れると、ボタンにはLoginと表示されます。それをユーザがクリックすると、Facebookのユーザ名とパスワードを入力するように求められます。もしユーザがあなたのサイトに登録していない場合は、ユーザはregistration-urlに指定されたURLへリダイレクトされます。すでに登録済みの場合はJavaScriptのonlogin()イベントが実行されます。このイベントが実行されれば、ユーザをサイトへログインさせるべきです。

Facebookへログインしているけどサイトへはユーザ登録していないという状況では、ボタンにはRegisterと表示され、クリックするとregistration-urlで指定したURLへ飛びます。

ユーザがFacebookにログイン中であなたのアプリにも登録済みの場合、ボタンにはLoginと表示され、クリックしても何も実行されません。(アプリ側でgetLoginStatusを用いてこの状態を感知して、ボタンを表示しないようにすべきです。)

best practices and diagramsを見て動作を把握し、アプリを構成する全体像を掴んでください。

Reading the data

データはsined requestとしてアプリへと渡されます。signed_requestパラメータが、データがFacebookから送られてきたものであることを確認するシンプルな方法です。このシグネチャはFacebookとあなたしか知らないapplication secretを利用しますので、誰かがデータを改ざんすれば、シグネチャは無効なものとなります。

signed requestについての詳細は、canvas authentication documentationをご覧ください。

signed_requestをデコードすると、以下のような形式のJSONオブジェクトになります。
{
   "oauth_token": "...big long string...",
   "algorithm": "HMAC-SHA256",
   "expires": 1291840400,
   "issued_at": 1291836800,
   "registration": {
      "name": "Paul Tarjan",
      "email": "fb@paulisageek.com",
      "location": {
         "name": "San Francisco, California",
         "id": 114952118516947
      },
      "gender": "male",
      "birthday": "12/16/1985",
      "like": true,
      "phone": "555-123-4567",
      "anniversary": "2/14/1998",
      "captain": "K",
      "force": "jedi",
      "live": {
         "name": "Denver, Colorado",
         "id": 115590505119035
      }
   },
   "registration_metadata": {
      "fields": "[
        {'name':'name'},
        {'name':'email'},
        {'name':'location'},
        {'name':'gender'},
        {'name':'birthday'},
        {'name':'password',   'view':'not_prefilled'},
        {'name':'like',  'description':'Do you like this plugin?', 'type':'checkbox',  'default':'checked'},
        {'name':'phone', 'description':'Phone Number', 'type':'text'},
        {'name':'anniversary','description':'Anniversary', 'type':'date'},
       
{'name':'captain', 'description':'Best Captain', 'type':'select',
'options':{'P':'Jean-Luc Picard','K':'James T. Kirk'}},
       
{'name':'force', 'description':'Which side?', 'type':'select',
'options':{'jedi':'Jedi','sith':'Sith'}, 'default':'sith'},
       
{'name':'live', 'description':'Best Place to Live', 'type':'typeahead',
'categories':['city','country','state_province']},
        {'name':'captcha'}
      ]"
   },
   "user_id": "218471"
}
この形式はGraph APIの出力と似るようにデザインされています。signed requestにregistration_metadataフィールドも含まれます。このフィールドがあなたの指定したfieldパラメータと一致することを確認して、このデータがあなたの登録フォームから着たものであることを保証すべきです。このフィールドを確認することの重要性は、advanced pageで説明しています。

Facebookアカウントを使わずに登録することを選んだ場合、auth_token/user_id/expiresパラメータはsigned requestには含まれません。

PHP Example reading signed_request

注意:your_app_idを自分のアプリのIDに置き換え、your_app_secretをアプリのsecret keyに置き換えてください。
<?php
define('FACEBOOK_APP_ID', 'your_app_id');
define('FACEBOOK_SECRET', 'your_app_secret');

function parse_signed_request($signed_request, $secret) {
  list($encoded_sig, $payload) = explode('.', $signed_request, 2);

  // decode the data
  $sig = base64_url_decode($encoded_sig);
  $data = json_decode(base64_url_decode($payload), true);

  if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
    error_log('Unknown algorithm. Expected HMAC-SHA256');
    return null;
  }

  // check sig
  $expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
  if ($sig !== $expected_sig) {
    error_log('Bad Signed JSON signature!');
    return null;
  }

  return $data;
}

function base64_url_decode($input) {
    return base64_decode(strtr($input, '-_', '+/'));
}

if ($_REQUEST) {
  echo '<p>signed_request contents:</p>';
  $response = parse_signed_request($_REQUEST['signed_request'],
                                   FACEBOOK_SECRET);
  echo '<pre>';
  print_r($response);
  echo '</pre>';
} else {
  echo '$_REQUEST is empty';
}
?>