เคล็ดลับ iframe คุกกี้ของบุคคลที่สาม Safari ไม่ทำงานอีกต่อไปหรือ


137

ดังนั้นนี่คือการแก้แค้นคำถามที่ว่า "ฉันจะได้รับคุกกี้บุคคลที่สามมาทำงานใน Safari ได้อย่างไร" แต่ฉันถามอีกครั้งเพราะฉันคิดว่าสนามเด็กเล่นมีการเปลี่ยนแปลงบางทีหลังจากเดือนกุมภาพันธ์ 2012 หนึ่งในเทคนิคมาตรฐานที่จะได้รับอันดับที่ 3 คุกกี้ปาร์ตี้ใน Safari มีดังนี้ใช้ javascript เพื่อ POST ไปยัง iframe ที่ซ่อนอยู่ มันใช้เพื่อหลอกให้ Safari คิดว่าผู้ใช้โต้ตอบกับเนื้อหาของบุคคลที่สามและอนุญาตให้มีการตั้งค่าคุกกี้

ฉันคิดว่าช่องโหว่นี้ปิดตัวลงหลังจากที่เกิดเรื่องอื้อฉาวที่ไม่รุนแรงซึ่งมีการเปิดเผยว่า Google กำลังใช้เคล็ดลับนั้นกับโฆษณาของตน อย่างน้อยที่สุดในขณะที่ใช้เคล็ดลับนี้ฉันไม่สามารถตั้งค่าคุกกี้ใน Safari ได้อย่างสมบูรณ์ ฉันค้นพบการโพสต์ทางอินเทอร์เน็ตแบบสุ่มที่อ้างว่า Apple กำลังปิดช่องโหว่ แต่ฉันไม่พบคำที่เป็นทางการ

ในฐานะที่เป็นทางเลือกฉันได้ลองออกแบบเฟรมหลักของบุคคลที่สามใหม่เพื่อที่คุณจะต้องคลิกปุ่มก่อนที่เนื้อหาจะโหลด แต่แม้กระทั่งการโต้ตอบโดยตรงในระดับนั้นก็ไม่เพียงพอที่จะละลายใจเย็นชาของซาฟารี

มีใครรู้บ้างไหมถ้า Safari ปิดช่องโหว่นี้อย่างแน่นอน ถ้าเป็นเช่นนั้นจะมีวิธีแก้ไขปัญหาอื่น ๆ (นอกเหนือจากด้วยตนเองรวมถึง ID เซสชั่นในทุกคำขอ)?


21
การใช้ iframe ของบุคคลที่สามที่ต้องการคุกกี้นั้นไม่ได้หมายถึงการโจมตีด้านความปลอดภัยอย่างแน่นอน! เราใช้เว็บช็อปที่ใช้ใน iframe ในโดเมนที่หลากหลายและมีปัญหาทุกอย่างกับ Safari ในตอนท้ายดังนั้นฉันจึงสนใจคำตอบสำหรับคำถามนี้ (ถูกกฎหมาย)
mscha

14
ค่อนข้างทุกคนที่สร้างแอพ Facebook มีปัญหากับ Safari แอพ Facebook ทำงานใน iframe และตามนิยามทั้งหมดมาจากบุคคลที่สาม นี่คือเหตุผลที่การสนับสนุนสำหรับ Safari บนแอพ Facebook เป็นเรื่องที่ไม่แน่นอน: คุณไม่สามารถใช้คุกกี้ได้
gs hurley

ฉันไม่สามารถทำซ้ำปัญหานี้ได้ใน Safari 5.1.7 ยอมรับคุกกี้จาก iframe แอพ Facebook ของฉันด้วยการตั้งค่าเริ่มต้น "ไม่มีคุกกี้ของบุคคลที่สาม" อย่างไรก็ตาม Chrome 19.0.1084.46 ที่มีการตั้งค่าเดียวกันจะบล็อกคุกกี้
Evgeny Shadchnev

4
Chrome 19+ ที่มีตัวเลือก (ขอบคุณ) ที่ไม่ใช่ค่าเริ่มต้น "บล็อกคุกกี้ของบุคคลที่สามและข้อมูลไซต์" คือ / แม้จะรุนแรงกว่า / มากกว่าการตั้งค่า "บล็อกคุกกี้จากบุคคลที่สามและผู้ลงโฆษณา" ของ Safari ใน Chrome แม้ว่าคุณจะเข้าชมโดเมนบุคคลที่สามและตั้งค่าคุกกี้พวกเขาจะไม่ถูกส่งไปยัง iframe ผู้ใช้จะต้องเพิ่ม "ข้อยกเว้น" สำหรับโดเมนของคุณในการตั้งค่าความปลอดภัยของ Chrome
Aaron Gibralter

คุณหมายถึงอะไรกับ ก.พ. 2555 มีการเปลี่ยนแปลงทางเทคนิคใน Safari หรือการเปลี่ยนแปลงทางกฎหมายหรือไม่?
ของเหลว

คำตอบ:


51

แค่ต้องการออกจากโซลูชันการทำงานที่เรียบง่ายที่นี่ซึ่งไม่ต้องการการโต้ตอบกับผู้ใช้ไม่จำเป็นต้องโต้ตอบกับผู้ใช้

ตามที่ระบุไว้ในโพสต์ฉันทำ :

โดยทั่วไปสิ่งที่คุณต้องทำคือโหลดหน้าเว็บของคุณที่ด้านบนสุดการจัดทำสร้างเซสชันและเปลี่ยนเส้นทางกลับไปที่ facebook

เพิ่มรหัสนี้ที่ด้านบนสุดของคุณindex.phpและตั้งค่า$page_urlเป็นแท็บ / URL สุดท้ายของแอปพลิเคชันและคุณจะเห็นว่าแอปพลิเคชันของคุณจะทำงานได้โดยไม่มีปัญหาใด ๆ

<?php
    // START SAFARI SESSION FIX
    session_start();
    $page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
    if (isset($_GET["start_session"]))
        die(header("Location:" . $page_url));

    if (!isset($_GET["sid"]))
        die(header("Location:?sid=" . session_id()));
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid):
?>
   <script>
        top.window.location="?start_session=true";
    </script>
<?php
    endif;
    // END SAFARI SESSION FIX
?>

หมายเหตุ: สิ่งนี้ถูกสร้างขึ้นมาสำหรับ facebook แต่จริง ๆ แล้วมันจะทำงานในสถานการณ์ที่คล้ายกันอื่น ๆ


แก้ไข 20-Dec-2012 - การรักษาคำขอลงนาม:

รหัสด้านบนไม่รักษาข้อมูลการโพสต์คำขอและคุณจะสูญเสียการลงชื่อ _request ถ้าแอปพลิเคชันของคุณขึ้นอยู่กับคำขอที่ลงนามแล้วโปรดลองใช้รหัสต่อไปนี้:

หมายเหตุ: นี่ยังอยู่ระหว่างการทดสอบอย่างถูกต้องและอาจมีเสถียรภาพน้อยกว่าเวอร์ชั่นแรก ใช้ความเสี่ยงของคุณเอง / ข้อเสนอแนะชื่นชม

(ขอบคุณCBroe ที่ชี้ให้ฉันไปในทิศทางที่ถูกต้องที่นี่เพื่อปรับปรุงการแก้ปัญหา)

// Start Session Fix
session_start();
$page_url = "http://www.facebook.com/pages/.../...?sk=app_...";
if (isset($_GET["start_session"]))
    die(header("Location:" . $page_url));
$sid = session_id();
if (!isset($_GET["sid"]))
{
    if(isset($_POST["signed_request"]))
       $_SESSION["signed_request"] = $_POST["signed_request"];
    die(header("Location:?sid=" . $sid));
}
if (empty($sid) || $_GET["sid"] != $sid)
    die('<script>top.window.location="?start_session=true";</script>');
// End Session Fix

ขอบคุณทำงานเหมือนมีเสน่ห์และใช้งานง่ายในแอพที่มีอยู่ :-)
SamiSalami

ดังนั้นอันนี้ใช้ได้กับการเปลี่ยนเส้นทางสองสามครั้งใช่ไหม
Aaron Gibralter

1
@hugoderhungrige คุณยินดีฉันเพิ่งเพิ่มรุ่นใหม่อย่าลังเลที่จะตรวจสอบว่าคุณต้องการที่จะรักษาคำขอลงนามในแอปของคุณ
Diogo Raminhos

1
@CBroe ขอบคุณมากสำหรับการชี้ว่า! คุณพูดถูกมันใช้งานได้ตั้งแต่นั้นเมื่อมีการร้องขอครั้งที่สองผู้ใช้ก็เริ่มเซสชันแล้ว! ฉันเดาว่า "คนตาบอดที่เลวร้ายที่สุดคือคนที่ไม่อยากเห็น"
Diogo Raminhos

1
@ Whitehite คุณสามารถให้กรณีทดสอบแสดง 1 และ 2?
Gajus

35

คุณบอกว่าคุณเต็มใจที่จะให้ผู้ใช้คลิกปุ่มก่อนที่เนื้อหาจะโหลด ทางออกของฉันคือการมีปุ่มเปิดหน้าต่างเบราว์เซอร์ใหม่ หน้าต่างนั้นตั้งค่าคุกกี้สำหรับโดเมนของฉันรีเฟรชตัวเปิดและจากนั้นปิด

ดังนั้นสคริปต์หลักของคุณอาจมีลักษณะดังนี้:

<?php if(count($_COOKIE) > 0): ?>
<!--Main Content Stuff-->
<?php else: ?>
<a href="/safari_cookie_fix.php" target="_blank">Click here to load content</a>
<?php endif ?>

จากนั้น safari_cookie_fix.php ดูเหมือนว่า:

<?php
setcookie("safari_test", "1");
?>
<html>
    <head>
        <title>Safari Fix</title>
        <script type="text/javascript" src="/libraries/prototype.min.js"></script>
    </head>
    <body>
    <script type="text/javascript">
    document.observe('dom:loaded', function(){
        window.opener.location.reload();
        window.close();
    })
    </script>
    This window should close automatically
    </body>
</html>

ฉันกำลังคิดถึงบางสิ่งเช่นนั้น ทำงานได้อย่างไร้ที่ติ ฉันโหลดพร้อมกับกล่องโต้ตอบการอนุญาต ขอบคุณ!
vwoelm

ดูเหมือนว่าสิ่งนี้จะทำงานเกี่ยวกับการตั้งค่าของ Safari และเมื่อความรู้ทั่วไปจะได้รับ axed เช่นเดียวกับ "โซลูชั่นอื่น ๆ " ฉันกำลังมองหาวิธีการแก้ปัญหาที่แตกต่างกันโดยสิ้นเชิงเพราะเห็นได้ชัดว่าคุกกี้ของบุคคลที่สามกลายเป็นปีศาจแม้ว่าจะใช้ในวิธีที่เหมาะสมก็ตาม
LocalPCGuy

1
วิธีนี้ใช้ได้ผลสำหรับฉัน แต่จำเป็นต้องมีป๊อปอัปหรือไม่ คุณสามารถเปลี่ยนเส้นทาง iframe ของคุณไปยังหน้าซาฟารีตั้งค่าคุกกี้จากนั้นนำกลับไปที่เกมด้วยส่วนหัวเปลี่ยนเส้นทางอีกครั้งได้หรือไม่ หรือคุณต้องการป๊อปอัปเพื่อให้ผู้ใช้มีรูปแบบการติดต่อโดยตรงกับเซิร์ฟเวอร์
Anthony Hastings

มันใช้งานได้ดี โชคดีที่การกดปุ่มเพื่อเริ่มต้นสิ่งนี้ไม่ใช่เรื่องใหญ่ในแอปของฉัน
littlered

@LocalPCGuy ฉันไม่แน่ใจว่าจะได้รับ axed เช่นโซลูชั่นอื่น ๆ เพราะต้องการให้ผู้ใช้คลิก / โต้ตอบกับหน้าเว็บจริง ๆ เพื่อให้ป๊อปอัปไม่ถูกบล็อก วิธีแก้ปัญหานี้ที่ Safari ใช้งานได้ดูเหมือนว่าจะทำงานได้ดี: ผู้โฆษณาจะไม่สามารถตั้งค่าคุกกี้ข้ามโดเมนได้อย่างลับๆและแอพที่ฝังจะต้องให้ผู้ใช้โต้ตอบก่อนที่จะสามารถตั้งค่าคุกกี้ได้
Aaron Gibralter

15

ฉันหลอก Safari ด้วย. htaccess:

#http://www.w3.org/P3P/validator.html
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"NOI DSP COR NID CUR ADM DEV OUR BUS\""
Header set Set-Cookie "test_cookie=1"
</IfModule>

และมันก็หยุดทำงานสำหรับฉันเช่นกัน แอพทั้งหมดของฉันสูญเสียเซสชันใน Safari และกำลังนำออกจาก Facebook ขณะที่ฉันกำลังรีบแก้ไขแอปเหล่านั้นฉันกำลังค้นหาวิธีแก้ไข ฉันจะให้คุณโพสต์

แก้ไข (2012-04-06): เห็นได้ชัดว่า Apple "แก้ไข" ด้วย 5.1.4 ฉันแน่ใจว่านี่เป็นปฏิกิริยาต่อสิ่ง Google: "มีปัญหาในการบังคับใช้นโยบายคุกกี้ของเว็บไซต์บุคคลที่สามสามารถตั้งค่าคุกกี้หากการตั้งค่า" บล็อกคุกกี้ "ใน Safari ถูกตั้งค่าเริ่มต้นเป็น" จากบุคคลที่สามและผู้โฆษณา " http://support.apple.com/kb/HT5190


1
เห็นได้ชัดว่า Apple "แก้ไข" ด้วย 5.1.4 ฉันแน่ใจว่านี่เป็นปฏิกิริยาต่อสิ่ง Google: "มีปัญหาในการบังคับใช้นโยบายคุกกี้ของเว็บไซต์บุคคลที่สามสามารถตั้งค่าคุกกี้หากการตั้งค่า" บล็อกคุกกี้ "ใน Safari ถูกตั้งค่าเริ่มต้นเป็น" จากบุคคลที่สามและผู้ลงโฆษณา ". support.apple.com/kb/HT5190
vwoelm

1
ดังนั้นฉันคิดว่าความคิดเห็นนี้โดย vwoelm นั้นใกล้เคียงที่สุดกับคำตอบที่ฉันกำลังมองหา ก่อนอื่นฉันต้องการการยืนยันว่า Apple ปิดช่องโหว่อย่างชัดเจนแล้วและการอ้างอิงถึงบทความสนับสนุนของ Apple ก็เป็นเช่นนั้น ส่วนที่สองของคำถามของฉัน แต่ยังคงเกี่ยวข้อง ช่วงของตัวเลือกสำหรับการแก้ไขปัญหาคืออะไร เห็นได้ชัดว่าเราสามารถเข้ารหัสรหัสเซสชันเป็น GET / POST params แต่ตัวเลือกอื่น ๆ คืออะไร ที่จัดเก็บในตัวเครื่องทำงานในบริบทนี้หรือไม่ แฟลชคุกกี้?
gs hurley

@ vwoelm: นั่นเป็นคำตอบที่ฉันต้องการ (แต่ไม่หวัง) หากคุณใส่คำตอบลงไปในคอมเม้นต์แทนที่จะเป็นคอมเม้นท์ฉันจะมอบรางวัลให้คุณ
mscha

3
@ gshurley ฉันคิดว่าการส่งรหัสเซสชันผ่าน GET / POST params เป็นตัวเลือกเดียว มันไม่ปลอดภัย แต่จากนั้นอีกครั้ง Facebook บังคับให้เราให้บริการแอพผ้าใบโดยไม่ต้องใช้ SSL และนอกจากสิ่งที่คุณจะได้รับจากการแฮ็คแอพ Facebook ฮ่า ๆ ๆ ? เราอยู่ในความเมตตาของ Apple และตอนนี้พวกเขาอยู่ในโหมดโหดร้าย
hekevintran

14

ในตัวควบคุม Ruby on Rails ของคุณคุณสามารถใช้:

private

before_filter :safari_cookie_fix

def safari_cookie_fix
  user_agent = UserAgent.parse(request.user_agent) # Uses useragent gem!
  if user_agent.browser == 'Safari' # we apply the fix..
    return if session[:safari_cookie_fixed] # it is already fixed.. continue
    if params[:safari_cookie_fix].present? # we should be top window and able to set cookies.. so fix the issue :)
      session[:safari_cookie_fixed] = true
      redirect_to params[:return_to]
    else
      # Redirect the top frame to your server..
      render :text => "<script>alert('start redirect');top.window.location='?safari_cookie_fix=true&return_to=#{set_your_return_url}';</script>"
    end
  end
end

ซาฟารีมีปัญหาที่คล้ายกันหรือไม่?
ทางรถไฟเริ่มต้น

คุณสามารถแทนที่ set_your_return_url เป็น request.env ['HTTP_REFERER'] เนื่องจากเราอยู่ใน iframe :-D
Luc Boissaye

ฉันได้ลองวิธีแก้ไขปัญหานี้แล้วและปัญหาเดียวคือฉันไม่สามารถกลับไปที่ URL iframe หลักได้ มีวิธีการใน Rails ในการรับ url ของ parent iframe หรือไม่? ขอบคุณ
idejuan

ฉันใช้เวลา แต่ในที่สุดฉันก็พบว่าวิธีที่ง่ายที่สุด (TMO) คือการเพิ่มมันเป็นพารามิเตอร์ข้อความค้นหาไปยัง URL การเปลี่ยนเส้นทางของแอพทางรถไฟ ง่ายและสะอาด
guyaloni

1
คำตอบนี้สร้างตัวเปลี่ยนเส้นทางแบบเปิดซึ่งเป็นปัญหาด้านความปลอดภัยทั่วไป redirect_to params[:return_to]รหัสที่เป็นอันตราย พารามิเตอร์นั้นจะต้องได้รับการตรวจสอบกับรายชื่อที่ปลอดภัยที่จะเปลี่ยนเส้นทางไปยัง ดูowasp.org/index.php/ …
phylae

13

สำหรับสถานการณ์เฉพาะของฉันฉันแก้ไขปัญหาโดยใช้ window.postMessage () และกำจัดการโต้ตอบของผู้ใช้ โปรดทราบว่านี่จะใช้งานได้หากคุณสามารถเรียกใช้ js ในหน้าต่างหลักได้ ไม่ว่าจะโดยการรวม js จากโดเมนของคุณหรือหากคุณมีการเข้าถึงแหล่งโดยตรง

ใน iframe (domain-b) ฉันตรวจสอบว่ามีคุกกี้อยู่หรือไม่หากไม่ได้ตั้งค่าไว้จะส่ง postMessage ให้กับผู้ปกครอง (domain-a) เช่น;

if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1
    && document.cookie.indexOf("safari_cookie_fix") < 0) {
    window.parent.postMessage(JSON.stringify({ event: "safariCookieFix", data: {} }));
}

จากนั้นในหน้าต่างหลัก (โดเมน - a) ฟังเหตุการณ์

if (typeof window.addEventListener !== "undefined") {
    window.addEventListener("message", messageReceived, false);
}

function messageReceived (e) {
    var data;

    if (e.origin !== "http://www.domain-b.com") {
        return;
    }

    try {
        data = JSON.parse(e.data);
    }
    catch (err) {
        return;
    }

    if (typeof data !== "object" || typeof data.event !== "string" || typeof data.data === "undefined") {
        return;
    }

    if (data.event === "safariCookieFix") {
        window.location.href = e.origin + "/safari/cookiefix"; // Or whatever your url is
        return;
    }
}

ในที่สุดบนเซิร์ฟเวอร์ของคุณ (http://www.domain-b.com/safari/cookiefix) คุณตั้งค่าคุกกี้และเปลี่ยนเส้นทางกลับไปยังที่ที่ผู้ใช้มาจาก ตัวอย่างด้านล่างคือการใช้ ASP.NET MVC

public class SafariController : Controller
{
    [HttpGet]
    public ActionResult CookieFix()
    {
        Response.Cookies.Add(new HttpCookie("safari_cookie_fix", "1"));

        return Redirect(Request.UrlReferrer != null ? Request.UrlReferrer.OriginalString : "http://www.domain-a.com/");
    }

}

คุณไม่ได้รับข้อผิดพลาดทางไวยากรณ์กับการเรียกไปยัง postMessage หรือไม่
akousmata

จำเป็นที่จะต้องเพิ่มพารามิเตอร์ที่สอง"*"เพื่อPostMessageแก้ไขข้อผิดพลาดไวยากรณ์
ไมเคิล Baldry

หวังว่าฉันจะให้คำตอบนี้ upvotes มากขึ้น มันเป็นวิธีที่ง่ายที่สุดและถูกต้องที่สุดในการแก้ไขปัญหานี้ ขอบคุณสำหรับการโพสต์มัน!
AaronP

9

ฉันมีปัญหาเดียวกันและวันนี้ฉันพบการแก้ไขที่ทำงานได้ดีสำหรับฉัน หากตัวแทนผู้ใช้มีSafariและไม่มีการตั้งค่าคุกกี้ฉันจะเปลี่ยนเส้นทางผู้ใช้ไปยัง OAuth Dialog:

<?php if ( ! count($_COOKIE) > 0 && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari')) { ?>
<script type="text/javascript">
    window.top.location.href = 'https://www.facebook.com/dialog/oauth/?client_id=APP_ID&redirect_uri=MY_TAB_URL&scope=SCOPE';
</script>
<?php } ?>

หลังจากการตรวจสอบสิทธิ์และขอสิทธิ์กล่องโต้ตอบ OAuth จะเปลี่ยนเส้นทางไปยัง URI ของฉันในตำแหน่งบนสุด ดังนั้นการตั้งค่าคุกกี้เป็นไปได้ สำหรับแอพ canvas และ tab tab ทั้งหมดของเราฉันได้รวมสคริปต์ต่อไปนี้แล้ว:

<script type="text/javascript">
    if (top.location.href==location.href) top.location.href = 'MY_TAB_URL';
</script>

ดังนั้นผู้ใช้จะถูกเปลี่ยนเส้นทางอีกครั้งไปที่แท็บหน้า Facebook ด้วยคุกกี้ที่ถูกต้องตั้งค่าแล้วและคำขอลงนามจะถูกโพสต์อีกครั้ง


เยี่ยมมากในเรื่องนี้ ฉันได้อัปเดตการตรวจสอบตัวแทนผู้ใช้เพื่อให้แน่ใจว่า Chrome ไม่ได้อยู่ในตัวแทนผู้ใช้เช่นกันเนื่องจาก Chrome มี Safari ในสตริงตัวแทนผู้ใช้ด้วย การเปลี่ยนเส้นทางไปยังหน้าโดเมนของคุณตั้งค่าคุกกี้ / เซสชันเริ่มต้นที่จำเป็นจากนั้นเปลี่ยนเส้นทางกลับไปที่แอปของคุณบน apps.facebook.com ทำงานได้อย่างมีเสน่ห์ ดูเหมือนว่าโง่ แต่ทำงานได้ดี ขอบคุณ Sascha สำหรับคำแนะนำ!
Mike

7

ในที่สุดฉันก็หาวิธีแก้ปัญหาคล้าย ๆ กับที่ Sascha จัดเตรียมไว้ แต่มีการปรับเล็กน้อยเนื่องจากฉันตั้งค่าคุกกี้อย่างชัดเจนใน PHP:

// excecute this code if user has not authorized the application yet
// $facebook object must have been created before

$accessToken = $_COOKIE['access_token']

if ( empty($accessToken) && strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') ) {

    $accessToken = $facebook->getAccessToken();
    $redirectUri = 'https://URL_WHERE_APP_IS_LOCATED?access_token=' . $accessToken;

} else {

    $redirectUri = 'https://apps.facebook.com/APP_NAMESPACE/';

}

// generate link to auth dialog
$linkToOauthDialog = $facebook->getLoginUrl(
    array(
        'scope'         =>  SCOPE_PARAMS,
        'redirect_uri'  =>  $redirectUri
    )
);

echo '<script>window.top.location.href="' . $linkToOauthDialog . '";</script>';

สิ่งนี้จะตรวจสอบว่าคุกกี้สามารถใช้ได้เมื่อเบราว์เซอร์ซาฟารี ในขั้นตอนถัดไปเราอยู่ในโดเมนแอปพลิเคชันคือ URI ที่ให้ไว้เป็น URL_WHERE_APP_IS_LOCATED ด้านบน

if (isset($_GET['accessToken'])) {

    // cookie has a lifetime of only 10 seconds, so that after
    // authorization it will disappear
    setcookie("access_token", $_GET['accessToken'], 10); 

} else {

  // depending on your application specific requirements
  // redirect, call or execute authorization code again
  // with the cookie now set, this should return FB Graph results

}

ดังนั้นหลังจากเปลี่ยนเส้นทางไปยังโดเมนแอปพลิเคชันคุกกี้จะถูกตั้งค่าไว้อย่างชัดเจนและฉันเปลี่ยนเส้นทางผู้ใช้ไปยังกระบวนการให้สิทธิ์

ในกรณีของฉัน (เนื่องจากฉันกำลังใช้ CakePHP แต่ควรทำงานได้ดีกับกรอบ MVC อื่น ๆ ) ฉันกำลังเรียกการดำเนินการเข้าสู่ระบบอีกครั้งเมื่อการอนุญาต FB ถูกดำเนินการอีกครั้งและในครั้งนี้ก็ประสบความสำเร็จเนื่องจากคุกกี้ที่มีอยู่

หลังจากได้รับอนุญาตแอปหนึ่งครั้งฉันไม่มีปัญหาในการใช้แอพกับ Safari (5.1.6) อีกต่อไป

หวังว่าจะช่วยทุกคน


1
สิ่งนี้ได้ผลสำหรับฉัน !! ขอบคุณ !! .. ฉันมีปัญหากับ Safari 5.1.7 .... ตอนนี้แก้ไขแล้ว!
Khalizar

5

ฉันมีปัญหานี้กับอุปกรณ์ที่ใช้ iOS ฉันสร้างร้านที่ฝังอยู่ในเว็บไซต์ปกติโดยใช้ iframe อย่างไรก็ตามในทุกหน้าผู้ใช้จะได้รับ sessionid ใหม่ทำให้ผู้ใช้ติดขัดระหว่างกระบวนการเนื่องจากค่าบางค่าไม่ปรากฏในเซสชัน

ฉันลองวิธีการแก้ปัญหาบางอย่างที่ให้ไว้ในหน้านี้ แต่ป๊อปอัปไม่ทำงานบน iPad ได้ดีและฉันต้องการโซลูชันที่โปร่งใสที่สุด

ฉันแก้ไขโดยใช้การเปลี่ยนเส้นทาง เว็บไซต์ที่ฝังไซต์ของฉันต้องเปลี่ยนเส้นทางผู้ใช้ไปยังเว็บไซต์ของฉันดังนั้นอันดับแรกเฟรมมี URL ไปยังเว็บไซต์ของฉันที่ฉันตั้งค่าคุกกี้และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าที่เหมาะสมบนเว็บไซต์ที่ฝังไซต์ของฉัน ผ่านใน url

ตัวอย่างรหัส PHP

เว็บไซต์ระยะไกลเปลี่ยนเส้นทางผู้ใช้ไปยัง

http://clientname.example.com/init.php?redir=http://www.domain.com/shop/frame

init.php

<?php
// set a cookie for a year
setcookie('initialized','1',time() + 3600 * 24 * 365, '/', '.domain.com', false, false);
header('location: ' . $_GET['redir']);
die;

ผู้ใช้จะสิ้นสุดลง http://www.domain.com/shop/frameเป็นที่ฝังเว็บไซต์ของฉันจัดเก็บเซสชันตามที่ควรและกินคุกกี้

หวังว่านี่จะช่วยใครซักคน


3

ให้ฉันแบ่งปันการแก้ไขของฉันใน ASP.NET MVC 4 ความคิดหลักเหมือนในคำตอบที่ถูกต้องสำหรับ PHP รหัสถัดไปเพิ่มในเค้าโครงหลักในส่วนหัวใกล้สคริปต์:

@if (Request.Browser.Browser=="Safari")
{
    string pageUrl = Request.Url.GetLeftPart(UriPartial.Path);
    if (Request.Params["safarifix"] != null && Request.Params["safarifix"] == "doSafariFix")
    {
        Session["IsActiveSession"] = true;
        Response.Redirect(pageUrl);
        Response.End();
    }
        else if(Session["IsActiveSession"]==null)
    {
        <script>top.window.location = "?safarifix=doSafariFix";</script>
    }
}

3

วิธีนี้ใช้ได้ในบางกรณี - ถ้าเป็นไปได้:

หากหน้าเนื้อหา iframe ใช้โดเมนย่อยของหน้าเว็บที่มี iframe คุกกี้จะไม่ถูกบล็อกอีกต่อไป


นี่เป็นข้อมูลที่เป็นประโยชน์ - สิ่งที่ฉันกำลังมองหา ในขณะที่ฉันแน่ใจว่าคนส่วนใหญ่ไม่สามารถเปลี่ยนโดเมนได้ มีเว็บไซต์ที่ฉันฝังสร้าง <mycompany> <theircompany>. com โดเมนย่อยที่แมปกับ IP ของฉันและ VHost ด้านข้างของฉันสำหรับโดเมนนั้นและใช้ URL นั้นใน iFrame ซับซ้อน แต่ควรกันกระสุนได้
Elocution Safari

1
สิ่งนี้อาจซับซ้อนหากคุณใช้ https กับโดเมนย่อยเนื่องจากเซิร์ฟเวอร์ย่อยจะต้องใช้ใบรับรอง SSL เพื่อให้ตรงกัน
Roger Halliburton

1

Google ปล่อยแมวออกจากกระเป๋าของอันนี้จริงๆ พวกเขาใช้มันเป็นระยะเวลาหนึ่งในการเข้าถึงคุกกี้ติดตาม มันได้รับการแก้ไขเกือบจะในทันทีโดย Apple = \

โพสต์วารสารวอลล์สตรีทเดิม


ฉันรู้เกี่ยวกับสิ่งต่าง ๆ ของ Google แต่ฉันไม่ได้เห็นอะไรเกี่ยวกับแอปเปิ้ล "แก้ไข" สิ่งนี้ (และทำลายอินเทอร์เน็ตครึ่งหนึ่ง) คุณมีรายละเอียดเกี่ยวกับเรื่องนี้ไหม?
mscha

1

นี่คือรหัสที่ฉันใช้ ฉันพบว่าหากฉันตั้งค่าคุกกี้ใด ๆ จากเว็บไซต์ของฉันคุกกี้นั้นจะทำงานใน iframe ได้อย่างน่าอัศจรรย์

http://developsocialapps.com/foundations-of-a-facebook-app-framework/

 if (isset($_GET['setdefaultcookie'])) {
        // top level page, set default cookie then redirect back to canvas page
        setcookie ('default',"1",0,"/");
        $url = substr($_SERVER['REQUEST_URI'],strrpos($_SERVER['REQUEST_URI'],"/")+1);
        $url = str_replace("setdefaultcookie","defaultcookieset",$url);
        $url = $facebookapp->getCanvasUrl($url);
        echo "<html>\n<body>\n<script>\ntop.location.href='".$url."';\n</script></body></html>";
        exit();
    } else if ((!isset($_COOKIE['default'])) && (!isset($_GET['defaultcookieset']))) {
        // no default cookie, so we need to redirect to top level and set
        $url = $_SERVER['REQUEST_URI'];
        if (strpos($url,"?") === false) $url .= "?";
        else $url .= "&";
        $url .= "setdefaultcookie=1";
        echo "<html>\n<body>\n<script>\ntop.location.href='".$url."';\n</script></body></html>";
        exit();
    }

1

รุ่นที่คล้ายกันเล็กน้อยใน PHP ของสิ่งที่คนอื่นโพสต์:

if (!isset($_COOKIE, $_COOKIE['PHPSESSID'])) {
    print '<script>top.window.location="https://example.com/?start_session=true";</script>';
    exit();
}

if (isset($_GET['start_session'])) {
    header("Location: https://apps.facebook.com/YOUR_APP_ID/");
    exit();
}

1

ฉันได้พบคำตอบที่สมบูรณ์แบบนี้ทุกคนต้องขอบคุณผู้ชายที่ชื่อว่าอัลลันซึ่งสมควรได้รับเครดิตทั้งหมดที่นี่ ( http://www.allannienhuis.com/archives/2013/11/03/blocked-3rd-party-session-cookies-in-iframes/ )

วิธีแก้ปัญหาของเขานั้นง่ายและเข้าใจง่าย

บนเซิร์ฟเวอร์เนื้อหา iframe (โดเมน 2) เพิ่มไฟล์ชื่อstartsession.phpที่ระดับโดเมนรูทที่มี:

<?php
// startsession.php
session_start();
$_SESSION['ensure_session'] = true;
die(header('location: '.$_GET['return']));

ตอนนี้ในเว็บไซต์ระดับบนสุดที่มี iframe (โดเมน 1) การเรียกไปยังหน้าที่มี iframe ควรมีลักษณะดังนี้:

<a href="https://domain2/startsession.php?return=http://domain1/pageWithiFrame.html">page with iFrame</a>

และนั่นมัน! Simples :)

เหตุผลที่ใช้งานได้เนื่องจากคุณกำลังนำเบราว์เซอร์ไปยัง URL ของบุคคลที่สามและบอกให้เชื่อถือได้ก่อนที่จะแสดงเนื้อหาจากภายใน iframe


0

ฉันใช้การแก้ไข (เพิ่มพารามิเตอร์ Sign_request ลงในลิงก์) เคล็ดลับของ Whiteagle และมันใช้ได้สำหรับ Safari แต่ IE ก็รีเฟรชหน้าเว็บอย่างต่อเนื่องในกรณีนั้น ดังนั้นโซลูชันของฉันสำหรับ Safari และ Internet Explorer คือ:

$fbapplink = 'https://apps.facebook.com/[appnamespace]/';
$isms = stripos($_SERVER['HTTP_USER_AGENT'], 'msie') !== false;

// safari fix
if(! $isms  && !isset($_SESSION['signed_request'])) {

    if (isset($_GET["start_session"])) {
        $_SESSION['signed_request'] = $_GET['signed_request'];
        die(header("Location:" . $fbapplink ));

    }
    if (!isset($_GET["sid"])) {
        die(header("Location:?sid=" . session_id() . '&signed_request='.$_REQUEST['signed_request']));
    }
    $sid = session_id();
    if (empty($sid) || $_GET["sid"] != $sid) {
    ?>
    <script>
        top.window.location="?start_session=true";
    </script>
    <?php
    exit;
    }
}

// IE fix
header('P3P: CP="CAO PSA OUR"');
header('P3P: CP="HONK"');


.. later in the code

$sr = $_REQUEST['signed_request'];
if($sr) {
        $_SESSION['signed_request'] = $sr;
} else {
        $sr = $_SESSION['signed_request'];
}

0

ฉันยังได้รับทุกข์จากปัญหานี้ แต่สุดท้ายได้รับการแก้ไขในขั้นต้นโดยตรงโหลด iframe url ในเบราว์เซอร์เช่นป๊อปอัพเล็ก ๆ เท่านั้นแล้วเข้าถึงค่าเซสชั่นภายใน iframe


-1

ฉันเพิ่งเจอปัญหาเดียวกันกับ Safari วิธีแก้ปัญหาที่ฉันพบนั้นขึ้นอยู่กับ Local Storage HTML5 API การใช้ที่จัดเก็บในตัวเครื่องคุณสามารถเลียนแบบคุกกี้ได้

นี่คือโพสต์บล็อกของฉันพร้อมรายละเอียด: http://log.scalemotion.com/2012/10/how-to-trick-safari-and-set-3rd-party.html



-2

ฉันตัดสินใจที่จะกำจัด$_SESSIONตัวแปรทั้งหมดเข้าด้วยกัน & เขียนเสื้อคลุมรอบ memcache เพื่อเลียนแบบเซสชัน

ตรวจสอบ https://github.com/manpreetssethi/utils/blob/master/Session_manager.php

Use-case: ทันทีที่ผู้ใช้เข้าสู่แอปเก็บคำขอที่เซ็นชื่อโดยใช้ Session_manager และเนื่องจากอยู่ในแคชคุณสามารถเข้าถึงได้ในหน้าใด ๆ ตั้งแต่นี้เป็นต้นไป

หมายเหตุ: สิ่งนี้จะไม่ทำงานเมื่อเรียกดูแบบส่วนตัวใน Safari เนื่องจาก session_id จะรีเซ็ตทุกครั้งที่มีการโหลดหน้าซ้ำ (โง่ Safari)


-9

คุณสามารถแก้ไขปัญหานี้ได้โดยการเพิ่มหัวข้อตามนโยบาย p3p .. ฉันมีปัญหาเดียวกันกับซาฟารีดังนั้นหลังจากเพิ่มส่วนหัวที่ด้านบนของไฟล์เพื่อแก้ไขปัญหาของฉัน

<?php
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
?>

คุณแน่ใจหรือไม่ว่าใช้งานได้กับ Safari เวอร์ชันล่าสุด เรามีส่วนหัว P3P มาหลายปีสำหรับ IE แต่ Safari ยังใช้งานไม่ได้
mscha

2
ลองล้างคุกกี้ทั้งหมดและทดสอบอีกครั้ง ปัญหาไม่แสดงตัวเองหากเบราว์เซอร์ของคุณมีคุกกี้สำหรับไซต์ iframed ของคุณอยู่แล้ว
rmarscher

อืมฉันไม่สามารถทำให้ส่วนหัว P3P ทำงานได้เช่นกัน พวกเขายังทำงานใน IE ได้!
เซทสีน้ำตาล

2
สิ่งนี้เคยทำงาน แต่สำหรับ Safari เวอร์ชันล่าสุดจะไม่เป็นเช่นนั้น ล้างแคชของคุณและลองอีกครั้ง ....
chantheman

2
ฉันต้องการระบุว่าวิธีนี้ใช้ได้ผล ทำให้แน่ใจว่าคุณลบคุกกี้ทั้งหมดในซาฟารี แล้วลองสิ่งนี้
dnuske
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.