加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

xmlhttprequest – AngularJS和位于不同域中的Jersey Webservice

发布时间:2020-12-17 07:39:34 所属栏目:安全 来源:网络整理
导读:亲爱的stackoverflow读者, 最近我一直在玩AngularJS和Java EE 6.我已经和泽西建立了一个webservice,并在Glassfish上部署了这个项目.因为我需要某种身份验证和OAuth实现,或者JDBCRealm似乎过度杀戮,所以我决定在用户??成功登录后创建一个会话. @POST@Path("/l
亲爱的stackoverflow读者,

最近我一直在玩AngularJS和Java EE 6.我已经和泽西建立了一个webservice,并在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网页登录,我将获得正确的用户名,并且已经放置一个会话.如果我发送GET请求到/ ping我确实从我登录的用户名.

我有一个AngularJS应用程序部署在需要登录的node.js webserver上.因为这个服务器是在另一个端口上的另一个域,我不得不忍受痛苦的启用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;
    }
}

这样做使我有可能将不同类型的HTTP请求从AngularJS发送到部署在glassfish上的Java EE 6应用程序.

问题是当我从AngularJS发送一个POST请求到/ login方法时,会创建一个会话,并且我确定我的用户名.但是当我向/ 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是真的

$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/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control#section_5

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读