2013-08-09 88 views
7

Sto scrivendo un app in python che accede a un server di Magento utilizzando OAuth/REST eccMagento REST API, l'utente dato il ruolo di amministrazione, ma l'accesso Solo Guest concesso

L'autenticazione OAuth è stato completato, ho il due token di consumo & i 2 token di accesso. All'interno di Magento stesso ho seguito i passaggi di configurazione descritti in numerosi blog: impostazione dei ruoli REST, Attributi & Consumatori e Autorizzazioni utente & Ruoli. L'ho passato 500 volte (sembra così!) E non vedo errori, l'utente usa il consumatore REST che ha autorizzato token, il ruolo dell'utente è Administrator, quindi su & così via.

Ho notato che c'era qualcosa di sbagliato quando, dopo aver completato il processo OAuth, ho provato a pubblicare un prodotto su Magento (il suo database è vuoto) e ho ricevuto un accesso negato 403. Un tentativo di ottenere lo stesso. Ho abilitato l'accesso API REST per Guest, e ora il Get riceve un array json vuoto e naturalmente il Post ha ancora il 403 - questo mi dice che Magento non sta guardando i token OAuth e mi sta loggando.

sembra che Magento si stia rifiutando di accettare i token consumer/access che ha generato durante il processo di autenticazione OAuth.

C'è un passaggio di configurazione che ho perso, o qualsiasi informazione che fornirà un modo per superare questo posto di blocco?

Edit: frammento di codice aggiunto al di sotto che mostra il metodo che sto utilizzando per interrogare Magento: -

from rauth.session import OAuth1Session 
session = OAuth1Session(consumer_key, consumer_secret, access_key, access_secret) 
headers = {'Content-Type': 'application/json', 'Accept': 'application/json'} 
r = session.get('http://mysite.com/api/rest/products', headers=headers) 
print r.json() 

Uscite: {u'messages ': {u'error': [{u'message ': u'Accesso negato ', codice u': 403}]}}

risposta

4

Non sono riuscito a trovare una soluzione utilizzando la libreria rauth come mostrato nell'esempio sopra, ma ero in grado di farlo funzionare usando oauthlib/requests_oauthlib come segue: -

from requests_oauthlib import OAuth1 as OAuth 
import requests 
oauth = OAuth(client_key=consumer_key, client_secret=consumer_secret, resource_owner_key=access_key, resource_owner_secret=access_secret) 
h = {'Content-Type': 'application/json', 'Accept': 'application/json'} 
r = requests.get(url='http://mysite.com/api/rest/products', headers=h, auth=oauth) 
print r 
print r.content 

print r produce "< Response [200]>" e r.content contiene l'elenco di prodotti json formattato.

Sto supponendo che rauth stia calcolando erroneamente il valore di nonce o forse la codifica è stata disattivata - qualcosa nella richiesta che ha prodotto è stato il rovesciamento di Magento, che quindi si rifiutava di concedere l'accesso.

4

Dopo ore di riflettere su questo problema che ho finalmente capito perché alcuni di noi ottenere il seguente errore:

Invalid auth/bad request (got a 403, expected HTTP/1.1 20X or a redirect) 
{"messages":{"error":[{"code":403,"message":"Access denied"}]}} 

Anche autorizza dopo successo admin/cliente.

Il problema purtroppo non è con Magento, ma molto probabilmente potrebbe essere la configurazione del server.

ho iniziato a cercare nel codice di Magento API2 e si rese conto che stavano facendo uso del metodo Zend_Controller_Request_Http "getHeader" per verificare l'autorizzazione OAuth.

seguito è riportato il codice per "getHeader()"

public function getHeader($header) 
{ 
    if (empty($header)) { 
     #require_once 'Zend/Controller/Request/Exception.php'; 
     throw new Zend_Controller_Request_Exception('An HTTP header name is required'); 
    } 

    // Try to get it from the $_SERVER array first 
    $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header)); 
    if (isset($_SERVER[$temp])) { 
     return $_SERVER[$temp]; 
    } 

    // This seems to be the only way to get the Authorization header on 
    // Apache 
    if (function_exists('apache_request_headers')) { 
     $headers = apache_request_headers(); 
     if (isset($headers[$header])) { 
      return $headers[$header]; 
     } 
     $header = strtolower($header); 
     foreach ($headers as $key => $value) { 
      if (strtolower($key) == $header) { 
       return $value; 
      } 
     } 
    } 

    return false; 
} 

passata a questa funzione da Magento classe "Mage_Api2_Model_Auth_Adapter_Oauth" è:

public function isApplicableToRequest(Mage_Api2_Model_Request $request) 
{ 
    $headerValue = $request->getHeader('Authorization'); 

    return $headerValue && 'oauth' === strtolower(substr($headerValue, 0, 5)); 
} 

Dal momento che "$ request-> getHeader (' Autorizzazione ') viene chiamato, ovvero la variabile $ header nella funzione getHeader è "Autorizzazione"

// Try to get it from the $_SERVER array first 
$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header)); 
if (isset($_SERVER[$temp])) { 
    return $_SERVER[$temp]; 
} 

La classe Zend converte quindi "Autorizzazione" in "HTTP_AUTHORIZATION" e la cerca nell'array $ _SERVER, questo è dove si trova il problema perché in quell'array i valori di autorizzazione si trovano in "$ _SERVER ['Autorizzazione']" non "$ _SERVER ['HTTP_AUTHORIZATION"] ", lo fanno perché altre variabili come CONTENT_TYPE sono memorizzate come HTTP_CONTENT_TYPE, ad eccezione di Autorizzazione.

Tuttavia, sembra come se Zend è consapevole di questo e, quindi, ho scritto il seguente codice:

// This seems to be the only way to get the Authorization header on 
// Apache 
if (function_exists('apache_request_headers')) { 
    $headers = apache_request_headers(); 
    if (isset($headers[$header])) { 
     return $headers[$header]; 
    } 
    $header = strtolower($header); 
    foreach ($headers as $key => $value) { 
     if (strtolower($key) == $header) { 
      return $value; 
     } 
    } 
} 

Il problema qui è che molti server là fuori non consentono "apache_request_headers", se si stanno affrontando questo problema è probabile che la tua società di hosting abbia disabilitato "apache_request_headers".

Ci sono 2 soluzioni qui:

  1. contattare il tuo host e chiedere loro di abilitare "apache_request_headers".
  2. Modificare la funzione getHeader ($ intestazione) in classe Zend_Controller_Request_Http

Sostituire:

$temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header)); 

Con:

$temp = ($header == 'Authorization') ? $header : 'HTTP_' . strtoupper(str_replace('-', '_', $header));