Autor Zpráva
Pavel Straka
Profil
Dobrý večer, rád bych požádal o radu zkušenějších.
Rád bych na web přidal funkci pro přihlašování uživatelů přes Facebook, ale mám malé nejasnosti.

Jako základ používám skript (respektive nějakou oficiální knihovnu Facebooku), který jsem stáhl zde: https://github.com/facebook/php-sdk/
Soubor jako příklad (example.php):
<?php
/**
 * Copyright 2011 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */                       

 session_unset();
require '../src/facebook.php';

// Create our Application instance (replace this with your appId and secret).
$facebook = new Facebook(array(
  'appId'  => '',
  'secret' => '',
));

// Get User ID
$user = $facebook->getUser();

// We may or may not have this data based on whether the user is logged in.
//
// If we have a $user id here, it means we know the user is logged into
// Facebook, but we don't know if the access token is valid. An access
// token is invalid if the user logged out of Facebook.

if ($user) {
  try {
    // Proceed knowing you have a logged in user who's authenticated.
    $user_profile = $facebook->api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  }
}

// Login or logout url will be needed depending on current user state.
if ($user) {
  $logoutUrl = $facebook->getLogoutUrl();
} else {
  $loginUrl = $facebook->getLoginUrl(array(
    'scope' => 'email'
));
}

// This call will always work since we are fetching public data.
//$naitik = $facebook->api('/naitik');

?>
<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
  <head>
    <title>php-sdk</title>
    <style>
      body {
        font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
      }
      h1 a {
        text-decoration: none;
        color: #3b5998;
      }
      h1 a:hover {
        text-decoration: underline;
      }
    </style>
  </head>
  <body>
    <h1>php-sdk</h1>

    <?php if ($user): ?>
      <a href="<?php echo $logoutUrl; ?>">Logout</a>
    <?php else: ?>
      <div>
        Login using OAuth 2.0 handled by the PHP SDK:
        <a href="<?php echo $loginUrl; ?>">Login with Facebook</a>
      </div>
    <?php endif ?>

    <h3>PHP Session</h3>
    <pre><?php print_r($_SESSION); ?></pre>

    <?php if ($user): ?>
      <h3>You</h3>
      <img src="https://graph.facebook.com/<?php echo $user; ?>/picture">

      <h3>Your User Object (/me)</h3>
      <pre><?php print_r($user_profile); ?></pre>
    <?php else: ?>
      <strong><em>You are not Connected.</em></strong>
    <?php endif ?>
  </body>
</html>

Vše mi funguje tak, jak má (klíčové je pro mě získání e-mailu uživatele), až na jednu věc: není možné se odhlásit. Když kliknu na Logout odkaz s vygenerovanou adresou, jsem sice odhlášen z Facebooku, ale v tomto souboru (example.php) jsou v sessions pořád uloženy access tokeny. Ani příkaz sessions_unset(); nepřináší žádný užitek.

Druhý problém je, že se mi zatím nepodařilo vymyslet ideální způsob respektive obecně princip přihlašování přes Facebook. Mám klasickou databázi uživatelů (mám i možnost klasické registrace). Jak mám postupovat v případě, že se přihlásí uživatel, který není registrován tímto klasickým způsobem? Navíc jsem narazil na problém, že můžu být registrován "klasickým" způsobem a na Facebooku se registruje někdo na můj e-mail a po přihlášení na web bude zmatené, kdo je kdo. Budu vděčný za každou radu někoho, kdo už s tím přišel do styku.

Děkuji všem.
Alphard
Profil
Tento příklad nepracuje s vlastní ímplementací registrování uživatelů.
Když jsem to naposledy implementoval před cca rokem, používal jsem facebook skd pouze na ověření identity přes facebook při přihlašování. Záznam o uživateli se uložil od db k dalším uživatelům, jen s jeho fb identifikátorem.
Odhlašování pak bylo řešené jako odhlášení z webu, z fb jsem už neodhlašoval.
joe
Profil
Alphard:
Odhlašování pak bylo řešené jako odhlášení z webu, z fb jsem už neodhlašoval.
Tím jsi porušoval podmínky (a nebyl jsi vůbec jediný), kde měli (aspoň před rokem, kdy jsem to implementoval já taky :-)) uvedeno, že odhlášení se musí provést i na Facebooku. Zřejmě z bezpečnostních důvodů.

Pavel Straka:
Na tom příkladu ti to tuším funguje. Přihlášeného ověřeného uživatele poznáš až v případě, že se ti načtou jeho profilová data. (řádek 39).

Na druhý "problém" hledej "oauth 2.0" a jak ho implementovat v PHP.
Alphard
Profil
[#3] joe
Jo no, četl jsem, já tam měl trvalé přihlášení, rozhodnutí jak to vyřešit s odhlášením z fb jsem nechal na "potom"... :-)
Když teď o tom mluvíš, asi bych zkusil z fb odhlásit hned po ověření identity uživatele, to byla tehdy žhavá varianta, ale projekt šel stejně do kytek, takže už pak nebylo potřeba to řešit.
Pavel Straka
Profil
Alphard: Aha, rozumím, jak to myslíš. Jen ověřím uživatele při přihlášení a pak uložím jeho e-mail klasicky do SESSION a o víc už se z tohoto hlediska nestarám. Děkuji Ti.

Joe: Zkoušel jsem hledat, ale neřeší to můj problém. Četl jsem i tvůj příspěvek tady: Registrace přes FB - zádrhel a inspiroval se tam. Když se uživatel přihlásí přes FB vytvořím mu tedy jednoduše účet v databázi. Když se ale pak bude chtít registrovat klasicky, objeví se mu hláška, že takový uživatel už existuje. A jak máš, prosím, řešeno, to o čem jsem psal, že může být zmatečné, kdo je kdo, v případě, že si někdo na FB registruje můj e-mail. Děkuji za pomoc.


Jen pro upřesnění - na webu rozpoznávám přihlášené uživatele podle e-mailu a chtěl bych u toho modelu zůstat.


Je způsob, že při prvním přihlášení přes Facebook vygeneruji uživateli heslo a zašlu na e-mail pro případ, že by se chtěl přihlásit klasickým způsobem, špatný? Myslím, že to někdo navrhoval v tom stromu, kde Joe řešil přihlášení přes Facebook. :)
joe
Profil
Alphard:
:) Osobně ale taky moc nechápu, proč by to tak mělo být - přihlásím se na různých webech přes Facebook a pak se na jednom odhlásím a odhlásí mě to všude? ...

Pavel Straka:
To můžeš řešit více způsoby, jak jsem tam psal. Záleží na tom, jaký si zvolíš. Pokud se poprvé přihlásí přes FB, vytvoříš si v db nového uživatele a můžeš mu vygenerovat náhodné heslo, které mu můžeš poslat na e-mail. Heslo po něm můžeš chtít až tehdy, když se rozhodne přihlásit klasickým způsobem, budeš posílat ověřovací link do e-mailu.

v případě, že si někdo na FB registruje můj e-mail
Tohle snad ani není možné. Předpokládám, že i registrace na Facebooku požaduje ověření e-mailové adresy, jinak by se jim tam registrovala hromada robotů ;-)
Str4wberry
Profil
Reakce na Pavla Straku:
Když se ale pak bude chtít registrovat klasicky, objeví se mu hláška, že takový uživatel už existuje.
A co místo toho zobrazit jenom informaci, že klasická registrace bude propojená s FB účtem a vesele pokračovat dál? Samozřejmě s e-mailovým potvrzením.

Reakce na joa:
Předpokládám, že i registrace na Facebooku požaduje ověření e-mailové adresy
Otázka je, jak to funguje při změně e-mailu. Ale to se taky ověřuje, tak v tom snad také problém nebude.
Alphard
Profil
Email je asi nejlepší možný identifikátor, představa, že někdo cizí má můj mail na fb nebo jinde pro mě není zrovna lákavá a doufám, že takové případy jsou naprosté výjimky.

Je způsob, že při prvním přihlášení přes Facebook vygeneruji uživateli heslo a zašlu na e-mail pro případ, že by se chtěl přihlásit klasickým způsobem, špatný?
Jestli tento uživatel bude mít normálně přistup do svého profilu stejného jako normálně registrovaní, bude pohodlnější, když si bude moci zadat heslo sám.
Pavel Straka
Profil
joe:Taky jsem se tomu divil, ale je to tak. Registrace na Facebook nevyžaduje potvrzení pomocí e-mailu.
Str4wberry: Ano, vyřeším to tak, že po prvním přihlášení přes FB vygeneruji / dám uživateli možnost nastavit si heslo pro případ klasického přihlášení.
Alphard: Ano ano, děkuji za rady.

Poslední otázka: Nevíte, jak docílit toho, aby odkaz k přihlášení přes Facebook vedl k otevření pop-up okna? Mně nyní vede sem: https://www.facebook.com/login.php a ten layout je tak široký, že zmenšení není možné.

Děkuji za pomoc.
joe
Profil
Pavel Straka:
Potvrzení e-mailové adresy je samozřejmě ze strany Facebooku nutností a bylo by bezpečnostní chybou, kdyby Facebook potvrzení nevyžadoval. Nevím jak jsi přišel k opaku.
Vytvořit profil si sice můžeš na e-mailovou adresu jakou chceš, tu pak ale musíš potvrdit, jinak je tvůj profil (pravděpodobně) silně omezen a určitě nemůžeš přistupovat k aplikacím (minimálně k těm, co vyžadují právě e-mailovou adresu).

Nevíte, jak docílit toho, aby odkaz k přihlášení přes Facebook vedl k otevření pop-up okna?
K tomu popupu co popisuješ se používá JavaScript SDK od Facebooku, i když by to asi šlo vytvořit i bez něj, je ztráta času vymýšlet něco, co už dávno je.
Pavel Straka
Profil
joe: Nenapadlo mě, že nějaké omezení přijde až potom, máš pravdu.
Ohledně toho popup okna: Upravil jsem takto část kódu:
$facebookLoginUrl = $facebook->getLoginUrl(array(
          'scope' => 'email',
          'display' => 'popup'
         )); 

A přihlášení se nyní otevírá v novém okně, problém ale je, že po úspěšném přihlášení se celý web načte do toho okýnka. Nemáš prosím nápad, jak jen toto upravit? Mám už celou věc napsanou na základě PHP SDK a nerad bych to měnil.

Děkuju za pomoc.
joe
Profil
Pavel Straka:
Třeba tak, že si to otevřené okno nějak pojmenuješ a jakmile by mělo dojít k přesměrování, spustíš JavaScript, který okno zavře a aktualizuje okno odkud bylo otevřeno. Z hlavy přesně nevím, musel bych hledat. Jinak tím, že použiješ JS SDK FB bys neměnil nic, jen to vlastně ještě rozšířil. Myslím teda, že pro správnou implementaci by mělo být použité jak PHP SDK tak i pro ten JS.
slovakCZ
Profil
Na tom příkladu ti to tuším funguje. Přihlášeného ověřeného uživatele poznáš až v případě, že se ti načtou jeho profilová data. (řádek 39).
joe:

resim ted podobny problem, nejsem schopen rozpoznat, zda je uzivatel opravdu na FB prihlasen. Pokud se totiz prihlasim a pustim skript, tak to projde.. pokud se z FB odhlasim a pustim skript ,tak to kupodivu projde taky a data o uzivateli se mi natahnou (zminovany radek 39).. problem nastava hlavne v pripade, ze jedna rodina bude chtit na strance neco provest, jeden clen se odhlasit a druhy pusti mou aplikaci, ktera si ale bude myslet, ze je porad prihlasen prvni clen.

Diky za tipy jak tento problem resit, uz jsem bez napadu :(

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: