您的位置:首页技术文章
文章详情页

AngularJS和位于另一个域的Jersey Webservice之间的通信无法访问正确的会话

浏览:31日期:2024-05-17 17:57:48
(adsbygoogle = window.adsbygoogle || []).push({}); 如何解决AngularJS和位于另一个域的Jersey Webservice之间的通信无法访问正确的会话?

根据您使用的AngularJS版本,您可能必须在每个$ http上进行设置。

从1.2开始,您可以执行以下操作:

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

从1.1.1起,您可以对其进行全局配置:

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

如果您使用的是Angular的旧版本,请尝试将配置对象传递给指定withCredentials的$ http。应该可以在1.1之前的版本中使用:

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

另请参阅mruelans答案和:

https://github.com/angular/angular.js/pull/1209http://docs.angularjs.org/api/ng.$httphttps://developer.mozilla.org/zh-CN/docs/HTTP/Access_control_CORS?redirectlocale=zh-CN&redirectslug=HTTP_access_control#section_5解决方法

最近,我一直在使用AngularJS和JavaEE6。我已经在Jersey上构建了一个Web服务,并在Glassfish上部署了该项目。因为我需要某种身份验证,并且需要OAuth实现或JDBCRealm,所以我决定仅在用户成功登录后才创建会话。

@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();}

如果我从Postman或从glassfish上部署的基本jQuery网页发布到/login,这似乎还可以,我确实获得了正确的用户名,并且已经建立了会话。然后,如果我向/ ping发送GET请求,则确实会获得我登录时使用的用户名。

我已经在需要登录的node.jsWeb服务器上部署了AngularJS应用程序。因为该服务器位于另一个域上的另一个端口上,所以我不得不经历启用cors的痛苦。我通过构建一个设置响应头的容器响应过滤器来做到这一点。

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向玻璃鱼上部署的Java EE 6应用程序发送不同类型的HTTP请求。

问题是,当我从AngularJS向/ login方法发送POST请求时,创建了一个会话,并且确实获得了我的用户名。但是,当我向/ping方法发送GET请求时,收到“未设置用户名属性的会话”通知。

我认为这与跨域防护有关,并且在发送xhr请求时必须设置withCredentials标记。我一直在尝试在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设置为true

$http.defaults.withCredentials = true;

但是,这并不能解决我的问题。我还尝试将它与config参数中的每个请求一起发送,但这也不能解决我的问题。

标签: web
相关文章: