问题描述
尊敬的读者计算器,
最近我一直在玩弄AngularJS和Java EE 6我已经建立与泽西互联网服务和部署在Glassfish项目。因为我需要某种形式的身份验证和一个OAuth实现或JDBCRealm似乎矫枉过正,我决定只创建一个会话,如果用户成功登录。
Lately I've been playing around with AngularJS and Java EE 6. I've build an webservice with Jersey and deployed the project on Glassfish. Because I needed some kind of authentication and an OAuth implementation or an JDBCRealm seemed overkill I decided to just create a session if the user successfully logged in.
@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();
}
这似乎好了工作,如果我发布到/登录从邮差或部署在GlassFish中我得到了正确的用户名和背部会话已被置于一个基本的jQuery的网页。如果我再发送一个GET请求/平我得到的用户名后面我从中登录。
This seems to work alright, if I post to /login from Postman or from a basic jQuery webpage deployed on glassfish I do get the correct username back and a session has been placed. If I then send a GET request to /ping I do get the username back from which I logged in.
我已经部署上需要登录一个Web服务器的Node.js的AngularJS应用。因为这个服务器是它的另一个端口上另一个域上,我不得不去通过使CORS的痛苦。我通过构建一个容器响应滤波器这台响应头这样做。
I've an AngularJS application deployed on a node.js webserver which needed to login. Because this server is on another port its on another domain and I had to go through the pain of enabling cors. I did this by building a container response filter which sets the response headers.
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;
}
}
这也使得我能够从AngularJS发送不同类型的HTTP请求到部署在GlassFish Java EE 6的应用程序。
This did made it possible for me to send different types of HTTP requests from AngularJS to Java EE 6 application deployed on glassfish.
问题是,当我从AngularJS发送POST请求到/ login方法,将创建一个会话,我得到我的用户名后面。但是,当我发送一个GET请求到/平的方法,我得到了与用户名属性没有会话已定的通知。
The problem is that when I send a POST request from AngularJS to the /login method, a session is created and I do get my username back. But when I send a GET request to the /ping method I get the "no session with an username attribute has been set" notice.
我相信这与跨域prevention做的,我已经设置withCredentials标签,当我发出XHR请求。我一直在努力做这AngularJS但还没有找到如何做到这一点。
I believe this has to do with cross domain prevention and that I've to set the withCredentials tag when I send a xhr request. I've been trying to do this in AngularJS but haven't found out how to do this.
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);
});
};
};
而在另一个控制器:
And in another controller:
$scope.getUsername = function() {
$http.get("glassfish:otherport/api/ping", {}).
success(function(data) {
$scope.username = data;
}).
error(function() {
$scope.username = "error";
})
}
我试过设置withCredentials是真的
I've tried to set withCredentials is true
$http.defaults.withCredentials = true;
不过,这并没有解决我的问题。我也试图与在配置参数每个请求发送但这并没有任何解决我的问题。
This however didn't solve my problem. I also tried to send it with every request in the config parameter but this didn't solve my problem either.
推荐答案
根据AngularJS的版本使用的是你可能必须将其设置在每个$ HTTP。
Depending on the version of AngularJS you are using you might have to set it on each $http.
由于1.2可以这样做:
Since 1.2 you can do:
$http.get(url,{ withCredentials: true, ...})
从1.1.1您可以全局配置:
From 1.1.1 you can globally configure it:
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]).
如果你使用的角度是旧版本,尝试通过一个配置对象$ HTTP指定withCredentials。这应该在工作版本之前1.1:
If you're using an older version of Angular, try passing a config object to $http that specifies withCredentials. That should work in versions before 1.1:
$http({withCredentials: true, ...}).get(...)
另请参见mruelans回答和:
See also mruelans answer and:
- https://github.com/angular/angular.js/pull/1209
- http://docs.angularjs.org/api/ng.$http
- https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control#section_5
这篇关于AngularJS和新泽西州的Webservice这是一个不同的域之间的通信。无法访问正确的会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!