การจัดการคุกกี้ใน PhoneGap / Cordova


89

ฉันกำลังทำงานกับแอป PhoneGap ที่มีการใช้งานเซสชันเซิร์ฟเวอร์ ต้องใช้คุกกี้เพื่อจัดการเซสชัน นอกจากนี้ควรจัดการคุกกี้จากตัวจัดสรรภาระงานด้วย ดังนั้นจึงไม่มีทางรอบ คุณจัดการกับคุกกี้ในแอป PhoneGap ของคุณอย่างไร?

ฉันได้ทำวิจัยสำเร็จแล้ว:

  • บางคนบอกว่าการจัดการคุกกี้อาจขึ้นอยู่กับเซิร์ฟเวอร์ที่ไม่ได้ตั้งค่าคุกกี้สำหรับตัวแทนผู้ใช้ที่ไม่รู้จัก (IIS): เซสชัน PhoneGap (คุกกี้) บน iOS
  • ในคุกกี้ JavaScript สามารถตั้งค่าด้วย document.cookie = ... แต่จะไม่ถูกบันทึกใน PhoneGap และสูญหาย ก่อนที่จะทำการร้องขอ xhr มันใช้งานได้
  • สามารถเรียกดูคุกกี้ได้หลังจากคำขอ xhr ด้วย xhr.getResponseHeader ('Set-Cookie') แต่เมื่อตั้งค่าบนเซิร์ฟเวอร์จริงเท่านั้น น่าเสียดายที่ jQuery ตัดส่วนหัว "คุกกี้" ออก
  • คุณสมบัติ JavaScript document.cookie ไม่ได้รับการกำหนดและไม่ได้รับการอัพเดตหลังจากการร้องขอ (xhr)
  • บางคนแนะนำให้ localStorage บันทึกรหัสเซสชันเป็นต้น แต่สคริปต์ทั้งหมดสามารถเข้าถึงได้และนี่อาจเป็นปัญหาด้านความปลอดภัย XSS คุกกี้สามารถแก้ไขปัญหานี้ได้โดยใช้แฟล็ก httponly
  • iOS: มีการปรับเปลี่ยนบางอย่างซึ่งจะเปลี่ยนพฤติกรรมของ webView เพื่อรองรับคุกกี้ แต่ดูเหมือนว่าจะใช้งานไม่ได้กับ iOS 6 และ PhoneGap 2.5: https://groups.google.com/forum/?fromgroups=#!topic/phonegap/ZJE1nxX63ow
  • ดูเหมือนว่าคุกกี้จะเปิดใช้งานโดยค่าเริ่มต้นใน AppDelegate.m (v2.5)

คุณหมายถึงอะไรสคริปต์ทั้งหมดสามารถเข้าถึง localStorage ได้? ฉันคิดว่ามันแยกกันและค่อนข้างเป็นแซนด์บ็อกซ์สำหรับแอพ PhoneGap แต่ละแอพ ... ไม่?
jayarjo


ปลั๊กอินนี้อาจช่วยได้หรือไม่? github.com/assembly/cordova-cookie-jar
J Chris A

คำตอบ:


68

เพื่อนฉันพยายามเกินไปโดยไม่ประสบความสำเร็จในการใช้คุกกี้กับ phonegap วิธีแก้ปัญหาคือใช้ localStorage

ตัวอย่างด่วนที่สำคัญ:

 var keyName = window.localStorage.key(0);

ตั้งค่าตัวอย่างด่วนของรายการ:

 window.localStorage.setItem("key", "value");

รับตัวอย่างรายการด่วน

 var value = window.localStorage.getItem("key");
 // value is now equal to "value"

ลบรายการตัวอย่างด่วน:

 window.localStorage.removeItem("key");

ล้างตัวอย่างด่วน:

 window.localStorage.clear();

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

var wl = window.location.href;
var mob = (wl.indexOf("android")>0);

ข้อมูลอ้างอิง: http://docs.phonegap.com/en/1.2.0/phonegap_storage_storage.md.html#localStorage http://cordova.apache.org/docs/en/6.x/cordova/storage/storage.html # page-toc-source

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

$(document).ready(function () {
    try {
        localStorage.setItem('test', '1');
    } catch (Err) {
        if (Err.message.indexOf('QuotaExceededError') > -1) {
            // Tell the user they are in anonymous mode
            // Sugest it to go to https://support.apple.com/pt-br/HT203036 to get help to disable it
            }
        }
    }
});

1
Tiago เกี่ยวกับคำตอบของคุณคุณช่วยชี้แจงได้ไหมว่าตัวเลือก localStorage ยังคงมีอยู่ (ไม่มีข้อมูลสูญหาย) จนกว่าจะถอนการติดตั้งแอป และเราสามารถพูดได้หรือไม่ว่าแอปอื่น ๆ ไม่สามารถเข้าถึงคู่คีย์ - ค่าที่ฉันตั้งไว้ในแอปของฉันได้
shamaleyte

2
@shamaleyte "LocalStorage ทำหน้าที่เหมือนแคชมากกว่าคุกกี้โดยที่ความคงอยู่ของแต่ละรายการขึ้นอยู่กับการตั้งค่าเบราว์เซอร์ของผู้ใช้และวิธีที่เบราว์เซอร์ใช้งาน (เนื่องจากไม่มีข้อกำหนดสำหรับมัน)" stackoverflow.com/questions/9948284/…
Tiago Gouvêa

โปรดอย่าใช้ localstorage ใน Cordova! ใน iOS กระบวนการของระบบสามารถล้างที่เก็บข้อมูลในเครื่องได้ตามต้องการ gonehybrid.com/…
Nico Westerdale

4

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

สิ่งที่ฉันค้นพบมีดังต่อไปนี้:

  • คุกกี้ที่ตั้งค่าผ่าน AJAX (เช่น jQuery $.get()หรือ$.post()) ไม่คงอยู่
  • คุกกี้ตั้งอยู่ใน 'inAppBrowser' ทำยังคงมีอยู่

วิธีที่จะทำให้คุกกี้ยังคงมีอยู่คือการใช้ปลั๊กอินinAppBrowser

ขั้นแรกตั้งค่าเซิร์ฟเวอร์อย่างง่ายที่ยอมรับเป็นพารามิเตอร์คีย์ - ค่าพารามิเตอร์ GET ที่คุณต้องการคงอยู่ ฉันเป็นงูหลาม / พายุทอร์นาโดเซิร์ฟเวอร์ของฉันอาจมีลักษณะดังนี้:

class PersistCookieHandler(tornado.web.RequestHandler):
   @tornado.gen.coroutine
   def get(self):
      token = self.get_argument('token')
      self.set_secure_cookie('token',token)

จากนั้นในแอปของคุณ:

function persistToken(token,success_cb, error_cb) {
    // replace with your URL
    url = 'SECURE_SERVER_URL_THAT_HANDLES_SET_COOKIE';  

    // _blank tells inAppBrowser to load in background (e.g., invisible)
    var ref = window.open(url, '_blank', 'location=no,toolbar=no');

    // attach a listener to the window which closes it when complete
    ref.addEventListener('loadstop', function(event) { 
        ref.close();
        success_cb();  // call our success callback
    });

    // attach a listener for server errors 
    ref.addEventListener('loaderror', function(event) { 
        // call our error callback
        error_cb(event);    
    });
}

จากนั้นคุณสามารถเรียกสิ่งนี้ได้ดังนี้:

persistToken(
   someToken,
   function() {
       console.log("token persisted");
   },
   function() {
       console.log("something went wrong);
   }
);

3

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


คุณยังสามารถส่งผ่านโพสต์ XmtHttpRequest เช่นใช้$.post()ใน jQuery จากนั้นตั้งค่าตัวแปรภายในเครื่อง หากคุณเข้ารหัสทุกอย่างก็ค่อนข้างปลอดภัย
JVE999

@ JVE999 จะเข้ารหัสคุกกี้ที่บันทึกโดยค่าเริ่มต้นโดยการดูเว็บได้อย่างไร?
LoveForDroid

3

ใช้device_idเพื่อระบุเรกคอร์ดบางอย่างบนฝั่งเซิร์ฟเวอร์ สร้างตารางฐานข้อมูลชื่อsessionบนเซิร์ฟเวอร์ของคุณกับdevice_id, cookiename, cookievalueและtimestampเป็นคอลัมน์

เมื่อลูกค้าเข้าถึงเว็บเซิร์ฟเวอร์ของคุณผ่านแอพ phonegap ให้รับdevice_idและจัดเก็บคุกกี้ในตารางของคุณ device_id hereทำหน้าที่เป็นเข้าถึง token ใน OAuth โปรโตคอล

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


3

ฉันใช้ Cordova 6.1 (เวอร์ชันใหม่ล่าสุดในขณะนี้) และจริงๆแล้วฉันพบสิ่งต่อไปนี้:

หากฉันตั้งค่าคุกกี้ผ่าน Javascript โดยใช้ document.cookie = ... มันจะไม่ทำงาน อย่างไรก็ตามหากฉันส่งฟังก์ชัน setCookie ผ่าน Ajax ไปยังเซิร์ฟเวอร์ด้วยฟังก์ชันเช่น

function setCookie(name, value, exdays) {

    if(isPhonegap() === true){
        var data = "typ=function&functionType=setCookie&name="+name+"&value="+value+"&exdays="+exdays;
        loadAjax(data, false);    
    }
    else if (!(document.cookie.indexOf("name") >= 0)){
            var expires;
            if (exdays) {
                var date = new Date();
                date.setTime(date.getTime()+(exdays*24*60*60*1000));
                expires = "; expires="+date.toGMTString();
            }
            else{
                expires = "";
            }
            document.cookie = name+"="+value+expires+"; path=/"; 
    }
} 

และตั้งค่าคุกกี้ที่ฝั่งเซิร์ฟเวอร์โดยใช้

setcookie($cookie, $value, $expires , "/" );

แล้วมันใช้งานได้จริง!

หวังว่านี่จะช่วยได้ ไชโย


0

มีปัญหาเดียวกันและตัดสินใจย้าย evrth ไปที่ localStorage ฉันเขียนปลั๊กอินเพื่อให้คุณสามารถใช้มันได้เช่นกัน: angular-cookies-mirror


0

แน่นอนคุณสามารถ.

แอพไอออนิกเพียงแค่ส่ง ajax requset คุกกี้ทำงานได้ดีหรือไม่ขึ้นอยู่กับเซิร์ฟเวอร์

ฉันทำงานกับเซิร์ฟเวอร์ python Django และเซิร์ฟเวอร์โหนดคุกกี้ทั้งสองทำงานได้ดีมาก

โค้ดโหนดด้านล่าง

app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("Access-Control-Allow-Credentials",true);
next();
});

api ที่เหลือ

router.get('/setCookies', function(req, res, next) {
var now = new Date();
var nextYear=new Date(now.setFullYear(now.getFullYear()+1));
//you can change the cookie key and value by your self here
res.cookie('cookiesTest', 'set cookies success,your cookies can be set by server', { expires: nextYear, httpOnly: true });
res.status(200)
res.end('SET COOKIES SUCCESS')
});

router.get('/getCookies', function(req, res, next) {
res.status(200)
res.end(JSON.stringify(req.cookies))
});

รหัสแอปไอออนิก

var server='http://[YOUR IP HERE]:3000'

$scope.setCookies=function() {
  $http({
    url: server + '/setCookies',
    method: 'GET'
  }).success(function (data, header, config, status) {
    alert('set cookies success,look console')
    $scope.setCookiesStatu=false
    console.log(data)
    $scope.cookiesValue=data
  }).error(function (data, header, config, status) {
    alert('set cookies error,check console or your server address is wrong')
    console.log(data)
  });
}

$scope.getCookies=function() {
  $http({
    url: server + '/getCookies',
    method: 'GET'
  }).success(function (data, header, config, status) {
    alert('get cookies success,look console')
    console.log(data)
    $scope.cookiesValue=data
  }).error(function (data, header, config, status) {
    alert('get cookies error,check console or your server address is wrong')
    console.log(data)
  });
}

คุณสามารถตรวจสอบรหัสแหล่งที่มาของฉันได้ที่นี่


0

ฉันคิดว่าคำถามเป็นพื้นฐานเกี่ยวกับการตั้งค่าคุกกี้ฝั่งไคลเอ็นต์สำหรับแอป Cordova ข้อมูลส่วนใหญ่ในหัวข้อนี้บอกเป็นนัยว่าการตั้งค่าคุกกี้ฝั่งไคลเอ็นต์ใช้ไม่ได้กับ Cordova

แต่ฉันพบปลั๊กอินที่ช่วยให้ฉันตั้งค่าคุกกี้ฝั่งไคลเอ็นต์สำหรับแอป Cordova ของฉัน

ตรวจสอบhttps://www.npmjs.com/package/cordova-plugin-cartegraph-cookie-master

มันใช้งานได้!


0

ฉันยังมีปัญหาคุกกี้เซสชันกับคำขอ Cordova + XHR คุกกี้จะหายไปทุกครั้งที่รีสตาร์ทแอป มีสองสิ่งที่ช่วยแก้ปัญหาของฉัน:

  1. คุกกี้ต้องมีวันหมดอายุ

  2. คำขอ XHR ทั้งหมดต้องมีแฟล็ก withCredentials ที่ตั้งค่าเป็น true

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