2012-12-10 17 views
6

Ich habe ein Problem, bei dem ich hoffe, dass Sie mir helfen können. Nehmen wir an, ich arbeite für eine hypothetische Firma namens "Blammo" und wir haben ein hypothetisches Produkt namens "Log". Ich versuche ein System einzurichten, wo sich jemand einloggen kann, um einige unserer Produkte zu loggen und einige unserer Produkte zu bestellen, und dann, wenn sie zum Kauf bereit sind, gehen Sie zu checkout.blammo.com, um für ihre Bestellung zu bezahlen. Schließlich möchte ich zulassen, dass Blammo ein neues hypothetisches Produkt mit seiner eigenen Website, rockfromblammo.com, auf den Markt bringt und diese Seite auch eine Sitzung mit checkout.blammo.com teilen kann, so dass Nutzer einen einzigen Einkaufswagen über beide Produkte haben können Websites.Sichere und flexible domänenübergreifende Sitzungen

Natürlich ist das oben beschriebene hypothetische Szenario nicht, wie meine Firma tatsächlich funktioniert, aber es ist ein gutes Beispiel dafür, was ich tun muss. Wir haben eine bestehende Benutzerdatenbank und wir haben die Möglichkeit, jeden unserer Benutzer auf einer unserer Websites zu authentifizieren. Mein Ziel ist es jedoch, Benutzern zu ermöglichen, nahtlos von einer Website zur anderen zu wechseln, ohne sich erneut authentifizieren zu müssen. Dies würde es uns auch ermöglichen, Daten wie einen Einkaufswagen nahtlos an die Kasse zu übertragen.

Ich habe (kurz) Lösungen wie OpenID angeschaut, aber ich muss in der Lage sein, jede Lösung, die wir haben, mit unserer bestehenden Authentifizierungsmethode zu integrieren, die nicht besonders robust ist. Gibt es einen guten Weg, dies allein durch PHP zu tun?

+0

Also im Grunde Ihrer Website mehr 2nd-Level-Domain-Namen anstelle von 'product.site.com' Art hat? –

+2

Ich denke, deine beste Lösung ist, rockfromblammo.com zu rockfrom.blammo.com umleiten zu lassen - Sicherheit ist ein großes Problem in solchen Dingen, und den Zugang zu einem Einkaufswagen zu zwei verschiedenen Domains zu öffnen, birgt das Risiko von Dritten herauszufinden, wie man das Gleiche macht. – Blazemonger

+0

@Blazonger Es ist nicht nur ein Sicherheitsrisiko, es kann nicht über Domänen hinweg durchgeführt werden. Es kann nur Cross-Subdomains sein! –

Antwort

7

Sie könnten "Cross-Over" -Links zwischen den Websites erstellen, um die Sitzung zu übertragen.

Die einfachste Möglichkeit besteht darin, die Sitzungs-ID über die Abfragezeichenfolge zu übergeben. z.B.

http://whateverblammo.com/?sessid=XXYYZZ 

Bevor Sie anfangen zu denken, dass jeder diese Informationen einfangen kann, überlegen Sie, wie Ihre Cookies übertragen werden; Wenn Sie kein SSL verwenden, gibt es keinen großen Unterschied für jemanden, der das Netzwerk abgreift.

Das bedeutet nicht, dass es sicher ist; Zum einen könnten die Benutzer die Adressleiste versehentlich kopieren und einfügen und so ihre Sitzung verlieren. Um diese Exposition zu begrenzen, könnten Sie sofort nach dem Empfangen auf eine Seite ohne die Sitzungs-ID umleiten.

Beachten Sie, dass die Verwendung von mcrypt() für die Sitzungs-ID wird nicht viel helfen, weil es nicht die Sichtbarkeit des Werts ist, dass das Problem ist; Session-Hijacking kümmert sich nicht um den zugrunde liegenden Wert, sondern nur die Reproduzierbarkeit der URL.

Sie müssen sicherstellen, dass die ID nur einmal verwendet werden kann; Dies kann durch Erstellen einer Session-Variablen durchgeführt werden, die den Überblick über die Verwendung hält zählen:

$_SESSION['extids'] = array(); 

$ext = md5(uniqid(mt_rand(), true)); // just a semi random diddy 
$_SESSION['extids'][$ext] = 1; 

$link = 'http://othersite/?' . http_build_query('sessid' => session_id() . '-' . $ext); 

Als erhalten:

list($sid, $ext) = explode('-', $_GET['sessid']); 
session_id($sid); 
session_start(); 
if (isset($_SESSION['extids'][$ext])) { 
    // okay, make sure it can't be used again 
    unset($_SESSION['extids'][$ext]); 
} 

Sie müssen diese Links jedes Mal eine Grenze überschritten wird, weil die Sitzung Vielleicht haben Sie sich seit dem letzten Mal regeneriert.

1

Sie müssen die Session-Cookie Domain so setzen:

session_set_cookie_params($lifetime,$path,'.site.com') 

Dies funktioniert nur, wenn die Standorte auf den gleichen Domain-Namen sind darunter TLD (Top Level Domain).

Siehe here für weitere Informationen

Alternativ, wenn Sie bei Versuch, den Zugang Sitzungen suchen Domänen kreuzen, wie in site1.net-site2.com, so kann dies nicht geschehen.

3

Es kann getan werden, aber nicht mit einfachen Cookies und es ist nicht trivial. Was Sie suchen, ist eine Single-Sign-On (SSO) -Lösung, ähnlich wie die Login-Adresse von Google bei i.google.com, gmail.com, youtube.com usw.

Ich habe OpenID verwendet, um dies in der Vergangenheit zu implementieren .

Die Grundidee besteht darin, eine einzige Authentifizierungsdomäne (Provider) zu verwenden. Wenn einer der Sites (Consumer) den Benutzer authentifizieren möchte, leiten sie ihn an die Authentifizierungsdomäne um. Wenn sie nicht angemeldet sind, können sie sich mit den von Ihnen gewünschten Details anmelden.

Wenn sie bereits angemeldet sind (selbst von einer anderen Zielseite), müssen sie sich nicht erneut anmelden.

Der Benutzer wird dann mit der Hinzufügung eines Tokens in der URL zurück an die Zielseite gesendet. Dieses Token wird vom Server der Zielwebsite verwendet, um zu überprüfen, ob der Benutzer beim Authentifizierungsserver authentifiziert wurde.

Dies ist eine sehr einfache Erklärung. Dies zu tun ist nicht schwer, es sicher tun ist viel mehr so. Die Details zum sicheren Erzeugen und Authentifizieren der Tokens sind der herausfordernde Teil. Aus diesem Grund schlage ich vor, auf einem gut entworfenen System wie OpenID aufzubauen.

0

Wenn es OK für Ihre Website auf Javascript angewiesen funktionieren, könnten Sie vermutlich in etwa wie folgt tun:

Sagen Sie bitte auf blammo.com eine Sitzung haben, und Sie wollen, dass es für den Zugriff von rockblammo.com. Auf der rockblammo.com Seite könntest du eine <script> von blammo.com/get-session.js laden, dies wird (von der Serverseite) die Session-ID zurückgeben. Sobald das zurückgegeben wird, fügen Sie ein neues <script>-Tag auf der Seite ein, das auf rockblammo.com/set-session.js?sessionId=XXX verweist, wobei XXX die Session-ID ist, die Sie gerade von blammo.com erhalten haben. Auf der Serverseite von rockblammo.com wird der Session-Cookie aktualisiert und auf diese Session-ID gesetzt. In Zukunft werden die beiden Seiten nun die gleiche Sitzungs-ID haben. Wenn sie Zugriff auf denselben Sitzungsspeicher im Back-End haben, sind sie synchronisiert.

z. die Ausgabe von blammo.com/get-session.js wäre:

var sessionId = "XXX"; 
var s = document.createElement("script"); 
s.src = "/set-session.js?sessionId=" + escape(sessionId); 
document.body.appendChild(s); 

Die Ausgabe von rockblammo.com/set-session.js wäre leer, aber einen HTTP-Header, wie die folgenden:

Set-Cookie: sessionId=XXX 

Wenn Sie nicht lieber auf Javascript angewiesen, könnten Sie wahrscheinlich dasselbe tun, indem Sie zwischen den beiden Standorten hin- und herleiten und die Session-ID in einem Abfragezeichenfolgenparameter (GET-Parameter) übergeben.

0

Im domainübergreifenden Ajax kann es vorkommen, dass der Cookie und die nachfolgende Sitzung für domänenübergreifende Anfragen verloren gehen. Für den Fall, werden Sie Ajax-Aufrufe von Ihnen Website example.com zu Ihrer Sub-Domain s2.example.com Sie benötigen verwenden, um Eigenschaften in Header für PHP werden machen:

header('Access-Control-Allow-Origin: https://example.com'); 
header('Access-Control-Allow-Credentials: true'); 

und in JS gehen Sie hinzufügen

xhrFields: { withCredentials: true } 

Andernfalls Cookies nicht übergeben werden, und sie können nicht von Sitzung auf dem Sub-Domain machen.

Voll JS Anfrage wird an Sub-Domain ohne sein verloren Sitzungs:

$.ajax({ 
    url: "https://s2.example.com/api.php?foo=1&bar=2", 
    xhrFields: { withCredentials: true }, 
    success:function(e){ 
     jsn=$.parseJSON(e); 
     if(jsn.status=="success") { 
       alert('OK!'); 
     } else { 
       alert('Error!'); 
     } 
    } 
})