当前位置: 首页 > 面试题库 >

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

郜彦
2023-03-14
问题内容

最近,我一直在使用AngularJS和Java
EE6。我已经在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.js
Web服务器上部署了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参数中的每个请求一起发送,但这也不能解决我的问题。


问题答案:

根据您使用的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/1209
  • http://docs.angularjs.org/api/ng.$http
  • https://developer.mozilla.org/zh-CN/docs/HTTP/Access_control_CORS?redirectlocale=zh-CN&redirectslug=HTTP_access_control#section_5


 类似资料:
  • 问题内容: 我正在写一个创建mp3 /音频播放器的指令。问题是一页中可以有许多音频播放器。我想做的是当一个正在播放而您又开始播放另一个音乐时,当前正在播放的音乐会暂停。如何使用角度指令实现这一目标? 提前致谢! 问题答案: 您也可以执行$ rootScope。$ broadcast 事件,例如。所有指令都可以预订此事件,并且它们可以通过停止自身来对此事件做出反应。您需要做的一件事就是传递有关正在启

  • 问题内容: 我是Angular.js的新手,我的应用程序需要指令之间的某些通信,我阅读了一些有关链接和需求的文档,但无法确切了解其工作原理。 对于一个简单的示例,我有:live小提琴:http : //jsfiddle.net/yw235n98/5/ 2个指令:firstDir,secondDir ::带有一些数据 firstDir具有单击功能,它将更改数据值 当firsDir单击功能被触发时,我

  • 本文向大家介绍AngularJS控制器controller正确的通信的方法,包括了AngularJS控制器controller正确的通信的方法的使用技巧和注意事项,需要的朋友参考一下 AngularJS是一款非常强大的前端MVC框架,AngularJS中的controller是个函数,用来向视图的作用域($scope)添加额外的功能,我们用它来给作用域对象设置初始状态,并添加自定义行为。 当我们在

  • 问题内容: 我想可能有许多角度模块连接到一个shellpage中的不同区域。但是AngularJS中的模块可以彼此“交谈”吗?如果是,怎么办? 问题答案: 模块可以通过多种方式进行交互或共享信息 可以将一个模块注入另一个模块,在这种情况下,容器模块可以访问已注入模块的所有元素。如果您查看有角的种子项目,则会为指令,控制器,过滤器等创建模块,就像这样 angular.module(“ myApp”,

  • 控制人员之间的正确通信方式是什么? 我目前正在使用一个可怕的软糖,涉及:

  • 想改进这个问题吗?通过编辑这篇文章添加细节并澄清问题。 我有A和B两个班: 正如您在类B中看到的,我有一个方法登录名,我在其中放入了两个变量。我想访问类A中这些变量的值。我怎么做? PS:我正在使用JAVA8,我是个新手。