2015-05-21 10 views
5

Sto lavorando con il pacchetto SammyK/Facebook e ho riscontrato un problema con l'accesso a Facebook su CSRF. In precedenza funzionava bene, ma in seguito ho dovuto disabilitare la protezione CSRF nel mio kernel.php per il corretto funzionamento dell'API. Ora ce l'ho aggiornato e ha aggiunto le righe sotto nel middlewareConvalida di falsificazione della richiesta tra siti non riuscita. Richiesto param "stato" mancante pacchetto Laravel Sammyk/Facebook

public function handle($request, Closure $next) { 
    $skip = array(
       'api/v1/signup', 
       'api/v1/login', 
       'api/v1/addContacts', 
       'api/v1/email' 
      ); 
    foreach ($skip as $key => $route) { 
     //skip csrf check on route 
     if($request->is($route)){ 
      return parent::addCookieToResponse($request, $next($request)); 
     } 
    } 
    return parent::handle($request, $next); 
    } 

Quindi questo permette web e API per funzionano come previsto, ma dato che avevo disabilitato il CSRF ottengo il Cross-site richiesta di convalida contraffazione riuscita. Errore "stato" param param necessario quando eseguo un accesso FB. Ho provato a eseguire il debug e ho trovato in FacebookRedirectLoginHelper la funzione validateCsrf() non ottiene lo stato salvato $savedState = $this->persistentDataHandler->get('state');
Non sono sicuro di come risolvere questo come idealmente dovrebbe funzionare ora. Ho provato a stampare sia $ stato e $ stato salvato che ottengo $ stato salvato come null.

class FacebookController extends Controller { 
    public function fbConnect(LaravelFacebookSdk $fb) 
    { 
     // Obtain an access token. 
    try { 
    $token = $fb 
     ->getRedirectLoginHelper() 
     ->getAccessToken(); 
    } catch (Facebook\Exceptions\FacebookSDKException $e) { 
      dd($e->getMessage()); 
    } 
    // Access token will be null if the user denied the request 
    // or if someone just hit this URL outside of the OAuth flow. 
if (! $token) { 
    // Get the redirect helper 
$helper = $fb->getRedirectLoginHelper(); 

    if (! $helper->getError()) { 
     abort(403, 'Unauthorized action.'); 
    } 

    // User denied the request 
    dd(
     $helper->getError(), 
     $helper->getErrorCode(), 
     $helper->getErrorReason(), 
     $helper->getErrorDescription() 
    ); 
    } 

risposta

6

Infine, guardando in codice FB, ho scoperto che il problema "Cross-site convalida request forgery riuscita. Richiesto param‘stato’mancante" e simili sono causati da PHP variabile $ _SESSION [ 'FBRLH_state'] che per qualche motivo "strano" quando FB chiama il file di callback di accesso.

Per risolverlo, memorizzo questa variabile "FBRLH_state" DOPO il richiamo della funzione $ helper-> getLoginUrl (...). È molto importante fare solo dopo che la chiamata di questa funzione è all'interno di questa funzione quando la variabile $ _SESSION ['FBRLH_state'] è popolata.

Di seguito un esempio del mio codice nel login.php:

$uri=$helper->getLoginUrl($uri, $permissions); 
foreach ($_SESSION as $k=>$v) {      
    if(strpos($k, "FBRLH_")!==FALSE) { 
     if(!setcookie($k, $v)) { 
      //what?? 
     } else { 
      $_COOKIE[$k]=$v; 
     } 
    } 
} 
var_dump($_COOKIE); 

E nel login-callback.php prima di chiamare tutto il codice FB:

foreach ($_COOKIE as $k=>$v) { 
    if(strpos($k, "FBRLH_")!==FALSE) { 
     $_SESSION[$k]=$v; 
    } 
} 

Ultimo, ma non meno importante, anche ricordare di includere il codice per la sessione PHP così ..

if(!session_id()) { 
    session_start(); 
} 
... 
... 
... 
... 
<?php session_write_close() ?> 

Spero che questa risposta si può contribuire a risparmiare 8-10 ore di lavoro :) Ciao, Alex.

+2

Dove io chiamo codice di sessione .... in login.php o login-callback.php – deemi

0

Questo è stato il mio mal di testa, quindi ho trovato un modo semplice per risolverlo.

find config/session.php e cambiare

'expire_on_close' => false,

a

'expire_on_close' => true,

+2

ho provato che e ancora lo stesso errore ** "Convalida della falsificazione della richiesta cross-site fallita. Param mancante" stato "param." ** – ihue

1

Per coloro che sono con codeigniter, si dovrà caricare automaticamente la libreria sessione.

Cambia la tua applicazione/config/autoload.php, le biblioteche devono includere 'sessione':

$autoload['libraries'] = array('session'); 
+0

In CodeIgniter funziona, grazie. – user2580401