2017-03-16 11 views
16

कई दिनों से अब मैं अपने एकल पृष्ठ एप्लिकेशन के लिए एक सुरक्षित प्रमाणीकरण और सत्र प्रबंधन तंत्र की तलाश में हूं। एसपीए और प्रमाणीकरण के बारे में कई ट्यूटोरियल और ब्लॉग पोस्टों के आधार पर, स्थानीय स्टोरेज में जेडब्ल्यूटी को संग्रहीत करना या नियमित कुकीज़ सबसे आम दृष्टिकोण प्रतीत होता है, लेकिन it's simply not a good idea to use JWTs for sessions इसलिए यह इस ऐप के लिए एक विकल्प नहीं है।एचटीपी के साथ सिंगल पेज एप्लिकेशन केवल कुकी-आधारित प्रमाणीकरण और सत्र प्रबंधन

आवश्यकताओं

  • लॉगिन revokable होना चाहिए। उदाहरण के लिए, यदि उपयोगकर्ता के खाते पर संदिग्ध गतिविधि का पता लगाया गया है, तो उस उपयोगकर्ता की पहुंच को तुरंत रद्द करना संभव है और इसमें एक नया लॉग इन होना आवश्यक है। इसी तरह, पासवर्ड रीसेट जैसी चीजें सभी मौजूदा लॉगिन को रद्द करनी चाहिए।
  • प्रमाणीकरण अजाक्स पर होना चाहिए। कोई ब्राउज़र पुनर्निर्देशन ("हार्ड" पुनर्निर्देशन) बाद में होना चाहिए। सभी नेविगेशन एसपीए के अंदर होना चाहिए।
  • सब कुछ क्रॉस-डोमेन काम करना चाहिए। एसपीए www.domain1.com पर होगा और सर्वर www.domain2.com पर होगा।
  • जावास्क्रिप्ट को सर्वर आईडी द्वारा भेजे गए संवेदनशील डेटा तक पहुंच नहीं होनी चाहिए, जैसे कि सत्र आईडी। यह एक्सएसएस हमलों को रोकने के लिए है जहां दुर्भावनापूर्ण स्क्रिप्ट नियमित कुकीज़, लोकल स्टोरेज या सत्र स्टोरेज से टोकन या सत्र आईडी चुरा सकती हैं।

आदर्श तंत्र HttpOnly कुकीज़ का उपयोग कर कुकी-आधारित प्रमाणीकरण प्रतीत होता है जिसमें सत्र आईडी होती है। प्रवाह इस तरह काम करेगा:

  1. उपयोगकर्ता लॉगिन पृष्ठ पर आता है और अपना उपयोगकर्ता नाम और पासवर्ड सबमिट करता है।
  2. सर्वर उपयोगकर्ता को प्रमाणित करता है और HttpOnly प्रतिक्रिया कुकी के रूप में सत्र आईडी भेजता है।
  3. एसपीए में सर्वर पर किए गए बाद के एक्सएचआर अनुरोधों में इस कुकी को शामिल किया गया है। ऐसा लगता है कि withCredentials विकल्प का उपयोग करना संभव है।
  4. जब एक सुरक्षित एंडपॉइंट पर अनुरोध किया जाता है, तो सर्वर कुकी की तलाश करता है। यदि पाया जाता है, तो यह सुनिश्चित करने के लिए कि सत्र अभी भी मान्य है, डेटाबेस डेटाबेस के विरुद्ध सत्र आईडी को पार करता है।
  5. जब उपयोगकर्ता लॉग आउट करता है, तो डेटाबेस डेटाबेस से हटा दिया जाता है। अगली बार जब उपयोगकर्ता साइट पर आता है, तो एसपीए को 401/403 प्रतिक्रिया मिलती है (क्योंकि सत्र समाप्त हो गया है), फिर उपयोगकर्ता को लॉगिन स्क्रीन पर ले जाता है।

क्योंकि कुकी HttpOnly झंडा है, जावास्क्रिप्ट इसकी सामग्री को पढ़ने के लिए सक्षम नहीं होगा, तो यह जब तक यह से भेजी जाएगी HTTPS हमलों से सुरक्षित होगा।

चुनौतियां

यहाँ विशिष्ट मुद्दा मैं में चलाने गया है। मेरा सर्वर सीओआरएस अनुरोधों को संभालने के लिए कॉन्फ़िगर किया गया है। (जब मैं Chrome की स्थानीय कुकीज़ जाँच यह वहाँ नहीं है)

HTTP/1.1 200 OK 
server: Cowboy 
date: Wed, 15 Mar 2017 22:35:46 GMT 
content-length: 59 
set-cookie: _myapp_key=SFMyNTYBbQAAABBn; path=/; HttpOnly 
content-type: application/json; charset=utf-8 
cache-control: max-age=0, private, must-revalidate 
x-request-id: qi2q2rtt7mpi9u9c703tp7idmfg4qs6o 
access-control-allow-origin: http://localhost:8080 
access-control-expose-headers: 
access-control-allow-credentials: true 
vary: Origin 

हालांकि, ब्राउज़र कुकी बचाने नहीं करता है: उपयोगकर्ता के सत्यापन के बाद, यह सही ढंग से कुकी जवाब में भेजता है।तो निम्न कोड चलता है जब:

context.axios.post(LOGIN_URL, creds).then(response => { 
    context.$router.push("/api/account") 
} 

और खाता पृष्ठ बनाई गई है:

created() { 
    this.axios.get(SERVER_URL + "/api/account/", {withCredentials: true}).then(response => { 
    //do stuff 
    } 
} 

इस कॉल शीर्षक में कुकी नहीं है। इसलिए सर्वर इसे अस्वीकार करता है।

GET /api/account/ HTTP/1.1 
Host: localhost:4000 
Connection: keep-alive 
Accept: application/json 
Origin: http://localhost:8080 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 
Referer: http://localhost:8080/ 
Accept-Encoding: gzip, deflate, sdch, br 
Accept-Language: en-US,en;q=0.8,tr;q=0.6 

मैं लॉगिन जवाब में यह प्राप्त करने के बाद कुछ यकीन है कि ब्राउज़र कुकी की बचत होती है बनाने के लिए विशेष करने की जरूरत है? मेरे द्वारा पढ़े गए विभिन्न स्रोतों ने कहा है कि ब्राउज़र केवल प्रतिक्रिया कुकीज को सहेजते हैं जब उपयोगकर्ता को रीडायरेक्ट किया जाता है, लेकिन मैं कोई "हार्ड" रीडायरेक्ट नहीं चाहता क्योंकि यह एक एसपीए है।

प्रश्न में एसपीए Vue.js में लिखा गया है, लेकिन मुझे लगता है कि यह सभी एसपीए पर लागू होता है। मैं सोच रहा हूं कि लोग इस परिदृश्य को कैसे संभालेंगे।

अन्य सामान मैं इस विषय पर पढ़ा है:

+0

हाय में php बस की पुष्टि करता है! क्या आपको इस मुद्दे का कारण मिला? – Yuriy

उत्तर

0

साख नियंत्रण स्थापित करने और कुकी इसलिए जब उसे चालू करने के लिए सुनिश्चित हो के साथ लॉगिन करने के लिए पोस्ट करना ताकि लौटाई कुकी ब्राउज़र में सहेजी जा सके।

1

मुझे यह Vue.js 2 पर credentials = true के साथ काम कर रहा है। क्लाइंट साइट से केवल आधे कहानी के प्रमाण पत्र सेट करना। साथ ही आप सर्वर से प्रतिक्रिया हेडर निर्धारित करने की आवश्यकता:

header("Access-Control-Allow-Origin: http://localhost:8080"); 
    header("Access-Control-Allow-Credentials: true"); 

आप इस तरह पहुंच-नियंत्रण-अनुमति दें-उत्पत्ति के लिए वाइल्डकार्ड का उपयोग नहीं कर सकते हैं:

header("Access-Control-Allow-Origin: *"); 

जब आप क्रेडेंशियल्स निर्दिष्ट करें: सच हेडर, आपको ऑर्गिन निर्दिष्ट करने की आवश्यकता है।

जैसा कि आप देख सकते हैं, यह एक PHP कोड है, आप इसे नोडजेएस या किसी भी सर्वर साइड स्क्रिप्टिंग भाषा में मॉडल कर सकते हैं जिसका आप उपयोग कर रहे हैं।

VueJS में मैं main.js में इस तरह क्रेडेंशियल्स सेट = true:

Vue.http.options.credentials = true 

घटक में, मैं सफलतापूर्वक ajax का उपयोग कर में लॉग इन:

<template> 
<div id="userprofile"> 
    <h2>User profile</h2> 
    {{init()}} 

</div> 
</template> 

<script> 
    export default { 
     name: 'UserProfile', 
     methods: { 
     init: function() { 


       // loggin in 
       console.log('Attempting to login'); 

      this.$http.get('https://localhost/api/login.php') 
      .then(resource => { 
      // logging response - Notice I don't send any user or password for testing purposes 

      }); 

      // check the user profile 

       console.log('Getting user profile'); 

       this.$http.get('https://localhost/api/userprofile.php') 
       .then(resource => { 
        console.log(resource.data); 
       }) 

     } 
    } 
    } 

</script> 

सर्वर साइड पर बातें बहुत सरल हैं: login.php किसी भी सत्यापन के बिना कुकी सेट करता है (नोट: यह केवल परीक्षण उद्देश्यों के लिए किया जाता है। आपको इस कोड को सत्यापन के बिना उत्पादन में उपयोग करने की सलाह नहीं दी जाती है)

<?php 

header("Access-Control-Allow-Origin: http://localhost:8080"); 
header("Access-Control-Allow-Credentials: true"); 

$cookie = setcookie('user', 'student', time()+3600, '/', 'localhost', false , true); 

if($cookie){ 
    echo "Logged in"; 
}else{ 
    echo "Can't set a cookie"; 
} 

अंत में, उपयोगकर्ता प्रोफाइल।एक कुकी = उपयोगकर्ता

<?php 

    header("Access-Control-Allow-Origin: http://localhost:8080"); 
    header("Access-Control-Allow-Credentials: true"); 


if(isset($_COOKIE['user'])){ 
    echo "Congratulations the user is ". $_COOKIE['user']; 

}else{ 
    echo "Not allowed to access"; 
} 

सफलतापूर्वक लॉग इन सेट है, तो

Successfully logged in

संबंधित मुद्दे