/[drupal]/contributions/modules/fb/fb_session.inc
ViewVC logotype

Contents of /contributions/modules/fb/fb_session.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.10 - (show annotations) (download) (as text)
Thu Sep 24 16:04:47 2009 UTC (2 months ago) by yogadex
Branch: MAIN
CVS Tags: HEAD
Changes since 1.9: +6 -5 lines
File MIME type: text/x-php
improved comments
1 <?php
2
3 /**
4 * Here we override Drupal's session management. Actually, we try not
5 * to change things, unless we're servicing a facebook app. We
6 * include drupal's session.inc at the end of this file so that
7 * default behavior will take place. But first we detect whether
8 * we're handling a facebook app and if so we do a few special things.
9 *
10 * We need to handle several cases: FBML canvas pages, iframe canvas
11 * pages, and facebook connect pages.
12 *
13 * In the FBML case, the request comes from facebook, not the user's
14 * browser. So we can't set cookies. Instead we look to $_REQUEST
15 * for facebook's session key. If found, we muck with $_COOKIE
16 * variables so that session.inc, when we include it later, will do
17 * reasonable things.
18 *
19 * One weak point is FBML canvas pages where the user is not logged
20 * in. In this case facebook gives us no session state info. This is
21 * difficult for drupal to deal with. Perhaps the best option is to
22 * require login for application pages. A must for any pages which
23 * require session to work.
24 *
25 * Iframe canvas pages are a tricky case. Here, we can set cookies on
26 * the browser. On the first iframe request, facebook will provide
27 * additional session state info. On subsequest requests, if iframe
28 * links to a local url (without target=_top) we won't have the
29 * facebook params.
30 *
31 * In general with iframes, the user could also be visiting the
32 * regular website. We don't want iframe sessions to compete with
33 * regular sessions, so we change the session_name.
34 *
35 * Some browsers (Safari) will not accept the cookies we assign to an
36 * iframe. Setting $conf[fb_session_cookieless_iframe] attempts to
37 * work around this.
38 *
39 * For Facebook Connect, we have to honor facebook's session state
40 * info, so that when a user logs out of facebook, they are also
41 * logged out of their connect session. Also, we want to preserve
42 * previous session state. So for example if a user is already logged
43 * into Drupal, we'll know that after they hit the connect button.
44 */
45
46 $orig_session_name = session_name();
47 if (isset($_COOKIE[$orig_session_name]))
48 $orig_session_id = $_COOKIE[$orig_session_name];
49 else
50 $orig_session_id = '';
51
52 $nid = _fb_settings_parse(FB_SETTINGS_APP_NID);
53
54 if ($nid && isset($_REQUEST['fb_sig_api_key'])) {
55 // Canvas page or event callback
56
57 // If facebook provides a session key, us it. Allows us to share
58 // a session between FBML and iframe, and when forms are submitted
59 // from FBML canvas pages.
60 $new_session_name = "fb_canvas_{$nid}_" . $orig_session_name;
61 if (isset($_REQUEST['fb_sig_session_key']))
62 $new_session_id = "fb_canvas_{$nid}_" . $_REQUEST['fb_sig_session_key'];
63 else if ($orig_session_id) {
64 // When user is logged into facebook, but not authorized app, cookies are honored. (confirm this???)
65 $new_session_id = "fb_canvas_{$nid}_" . $orig_session_id;
66 }
67 else {
68 // If we have no session (user not logged into facebook) all such users will share one session!!!
69 $new_session_id = "fb_canvas_{$nid}_shared_session";
70 }
71
72 // Force url() to include the cookie-less session when in iframe
73 if (variable_get('fb_session_cookieless_iframe', FALSE) &&
74 isset($_REQUEST['fb_sig_in_iframe']) &&
75 $_REQUEST['fb_sig_in_iframe']) {
76 fb_settings(FB_SETTINGS_SESSION_KEY, $_REQUEST['fb_sig_session_key']);
77 }
78 }
79 else if ($nid && variable_get('fb_session_cookieless_iframe', FALSE) &&
80 ($sess_key = _fb_settings_parse(FB_SETTINGS_SESSION_KEY))) {
81 // using sessionless iframes
82 // similar logic to clause above, using session key in url path
83 $new_session_id = "fb_canvas_{$nid}_" . $sess_key;
84 $new_session_name = "fb_canvas_{$nid}_" . $orig_session_name;
85 }
86 else {
87 // Try to learn session key from cookies (Facebook Connect)
88
89 $apikey = NULL;
90 // Discover APIKEY by inspecting cookies.
91 // This could be made more efficient by looking only for the primary apikey. I hesitate because some sites may need to support multiple connect apps. (I.e. one for the website and other for resizeable iframes in canvas pages)
92 foreach ($_COOKIE as $key => $value) {
93 if ($pos = strpos($key, '_session_key')) {
94 $apikey = substr($key, 0, $pos);
95 }
96 }
97
98 if ($apikey && isset($_COOKIE[$apikey . '_ss'])) {
99 // We're logged into Facebook Connect.
100 // If fbConnect, we want to use another session id, so that if the
101 // user logs out of facebook, they are also logged out of drupal.
102
103 // Use globals to remember some values, for fb_connect.module to use.
104 $GLOBALS['fb_connect_apikey'] = $apikey;
105
106 // Rename the session id, so the Facebook Connect session is distinct from the original drupal session.
107 $new_session_id = 'fb_connect_' . $_COOKIE[$apikey . '_session_key'];
108
109 }
110 }
111
112 if (isset($new_session_name)) {
113 session_name($new_session_name);
114 }
115
116 if (isset($new_session_id)) {
117 if (!variable_get('fb_session_long_keys', TRUE)) {
118 // Facebook appends user id, time and expiry info which is not necessary for uniqueness. Here we truncate that information to ensure the sid fits in sessions table.
119 $new_session_id = substr($new_session_id, 0, 64);
120 }
121 if ($new_session_id != $orig_session_id) {
122 session_id($new_session_id);
123 if (isset($GLOBALS['fb_connect_apikey'])) {
124 // We can preserve the session state when going into fbconnect
125 db_query("DELETE FROM {sessions} WHERE sid='%s'", $new_session_id);
126 db_query("UPDATE {sessions} SET sid = '%s' WHERE sid = '%s'", $new_session_id, $orig_session_id);
127 }
128
129 // If we've changed the session id, disable drupal's caching
130 $GLOBALS['conf']['cache'] = 0;
131 }
132 }
133 else {
134 // No session from facebook, so make sure we're not using an out of date one.
135 if (strpos($orig_session_id, 'fb_connect') === 0) {
136 // Old fbconnect session can be deleted
137 db_query("DELETE FROM {sessions} WHERE sid='%s'", $orig_session_id);
138 session_id(md5(uniqid(microtime()) . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']));
139 }
140 else if (strpos($orig_session_id, 'fb_connect') === 0) {
141 // Canvas session should not be deleted as it could be a user visiting both the website and an iframe app
142 if (!$nid)
143 session_id(md5(uniqid(microtime()) . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']));
144 }
145 }
146
147
148 if ($nid && !isset($_COOKIE[session_name()])) {
149 // requests from facebook (FBML canvas pages) will not have cookies.
150 // We want Drupal's session.inc to work properly, as if the session
151 // came via cookie.
152 if (!$_COOKIE || !count($_COOKIE))
153 // Remember that cookies are actually disabled, some apps will want to display a message and/or redirect in this case.
154 $_COOKIE['_fb_cookie_fake'] = TRUE;
155 $_COOKIE[session_name()] = session_id();
156 }
157
158
159 // Finally, include the logic of Drupal's session.inc
160 include('includes/session.inc');
161
162 ?>

  ViewVC Help
Powered by ViewVC 1.1.2