2012-12-05 29 views
12

हाल ही में मैं एंगुलरजेएस और जावा ईई 6 के साथ खेल रहा हूं। मैंने जर्सी के साथ एक webservice का निर्माण किया है और ग्लासफ़िश पर प्रोजेक्ट को तैनात किया है। क्योंकि मैं प्रमाणीकरण के कुछ प्रकार के और एक OAuth क्रियान्वयन की आवश्यकता नहीं है या एक JDBCRealm लग रहा था overkill मैं सिर्फ अगर उपयोगकर्ता सफलतापूर्वक प्रवेश कर एक सत्र बनाने का फैसला किया।एंगुलरजेएस और एक जर्सी वेबसाइट सेवा के बीच संचार जो एक अलग डोमेन पर हैं। सही सत्र

@POST 
@Path("/login") 
@Produces({MediaType.APPLICATION_JSON}) 
@Consumes({MediaType.APPLICATION_JSON}) 
public Response login(LoginDAO loginData, @Context HttpServletRequest req) { 
    req.getSession().invalidate(); 
    loginData.setPassword(PasswordGenerator.hash(loginData.getPassword())); 
    User foundUser = database.login(loginData); 
    if(foundUser == null) { 
     return Response.status(Status.CONFLICT).build(); 
    } 
    req.getSession(true).setAttribute("username", foundUser.getUsername()); 
    return Response.ok().build(); 
} 

@GET 
@Path("/ping") 
public Response ping(@Context HttpServletRequest req) { 
    if(req.getSession().getAttribute("username") == null) { 
     return Response.ok("no session with an username attribute has been set").build(); 
    } 
    return Response.ok(req.getSession(true).getAttribute("username")).build(); 
} 

यह ठीक काम करने के लिए अगर मैं से/लॉगिन करने के लिए पोस्ट लगता है पोस्टमैन या ग्लासफ़िश पर तैनात मूल jQuery वेबपृष्ठ से मुझे सही उपयोगकर्ता नाम वापस मिलता है और एक सत्र रखा गया है। अगर मैं/जीईटी के लिए एक जीईटी अनुरोध भेजता हूं तो मुझे उपयोगकर्ता नाम वापस प्राप्त किया जाता है, जिसमें से मैंने लॉग इन किया है।

मेरे पास एक कोणीय जेएस एप्लिकेशन है जो लॉगिन करने के लिए आवश्यक node.js webserver पर तैनात है। चूंकि यह सर्वर किसी अन्य बंदरगाह पर दूसरे डोमेन पर है और मुझे कॉर्स को सक्षम करने के दर्द से गुजरना पड़ा। मैंने यह एक कंटेनर प्रतिक्रिया फ़िल्टर बनाकर किया जो प्रतिक्रिया शीर्षलेख सेट करता है।

public class CrossOriginResourceSharingFilter implements ContainerResponseFilter { 
    @Override 
    public ContainerResponse filter(ContainerRequest creq, ContainerResponse cresp) { 
     cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "http://localhost:8000"); 
     cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true"); 
     cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); 
     cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With"); 
     return cresp; 
    } 
} 

यह संभव बना दिया था मुझे जावा ईई 6 आवेदन glassfish पर तैनात करने के लिए AngularJS से HTTP अनुरोध के विभिन्न प्रकार के भेजने के लिए।

समस्या यह है कि जब मैं AngularJS से/लॉगिन विधि से POST अनुरोध भेजता हूं, तो एक सत्र बनाया जाता है और मुझे अपना उपयोगकर्ता नाम वापस मिल जाता है। लेकिन जब मैं/पिंग विधि को एक GET अनुरोध भेजता हूं तो मुझे "उपयोगकर्ता नाम विशेषता के साथ कोई सत्र सेट नहीं किया गया" नोटिस मिलता है।

मेरा मानना ​​है कि इसे क्रॉस डोमेन रोकथाम के साथ करना है और जब मैं xhr अनुरोध भेजता हूं तो मुझे प्रमाणपत्रों को टैग करना होगा। मैं AngularJS में ऐसा करने की कोशिश कर रहा हूं लेकिन यह नहीं पता कि यह कैसे करें।

function LoginCtrl($scope, $http) { 
    $scope.login = function() { 
     $http.post("glassfish:otherport/api/login", $scope.credentials). 
      success(function(data) { 
       console.log(data); 
      }). 
      error(function(data, error) { 
       console.log(error); 
      }); 
    }; 
}; 

और एक और नियंत्रक में:

$scope.getUsername = function() { 
    $http.get("glassfish:otherport/api/ping", {}). 
     success(function(data) { 
      $scope.username = data; 
     }). 
     error(function() { 
      $scope.username = "error"; 
     }) 
    } 

मैं withCredentials स्थापित करने के लिए कोशिश की है

$http.defaults.withCredentials = true; 

हालांकि यह मेरी समस्या का समाधान नहीं सच है। मैंने इसे कॉन्फ़िगर पैरामीटर में प्रत्येक अनुरोध के साथ भेजने की भी कोशिश की लेकिन इससे मेरी समस्या हल नहीं हुई।

उत्तर

19

AngularJS के संस्करण के आधार पर आप इसका उपयोग कर रहे हैं, आपको इसे प्रत्येक $ http पर सेट करना पड़ सकता है।

1.2 जब से तुम कर सकते हैं:

$http.get(url,{ withCredentials: true, ...}) 

1.1.1 से आप विश्व स्तर पर यह कॉन्फ़िगर कर सकते हैं:

config(['$httpProvider', function($httpProvider) { 
    $httpProvider.defaults.withCredentials = true; 
}]). 

आप कोणीय के एक पुराने संस्करण का उपयोग कर रहे हैं, तो एक config वस्तु गुजर कोशिश $ http से जो प्रमाण पत्र के साथ निर्दिष्ट करता है। यह 1 से पहले संस्करणों में काम करना चाहिए।1:

$http({withCredentials: true, ...}).get(...) 

भी देखें जवाब mruelans और:

5

सिर्फ एक अद्यतन anwser @iwein को, कि अब हम में सेट कर सकते हैं कॉन्फ़िगर स्वयं

config(['$httpProvider', function($httpProvider) { 
    $httpProvider.defaults.withCredentials = true; 
}]). 

https://github.com/angular/angular.js/pull/1209

(केवल अस्थिर संस्करण के बाद उपलब्ध: 1.1.1) 1.2 संस्करण में

+0

बहुत उपयोगी जोड़ +1 – iwein

5

, यह मेरे लिए काम नहीं करता:

$http({withCredentials: true, ...}).get(...) 

अगर मैं दस्तावेज़ पढ़ें, शॉर्टकट विधि को कॉन्फ़िगरेशन ऑब्जेक्ट

$http.get(url,{ withCredentials: true, ...}) 

$ http एक सिंगलटन लेना चाहिए , क्रेडेंशियल्स के साथ और बिना किसी एप्लिकेशन अनुरोध में मिश्रण करने का यही एकमात्र तरीका है।

+0

यह –

+0

जोड़ने के लिए धन्यवाद धन्यवाद, वे उस एपीआई को बदलते रहते हैं ... – iwein

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

  • कोई संबंधित समस्या नहीं^_^