2012-12-05 1 views
12

最近AngularJSとJava EE 6で遊んでいます。私はJerseyでWebサービスを構築し、Glassfishでこのプロジェクトを展開しました。私は、認証のいくつかの種類を必要とし、OAuthを実装またはJDBCレルムは行き過ぎ私は、ユーザーが正常にログインした場合だけでセッションを作成することを決めた。異なるドメインにあるAngularJSとJersey Webservice間の通信。正しいセッションにアクセスできない

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

Iから/ログインに投稿する場合、これは、無事動作しているように思えたのでPostmanまたはglassfishにデプロイされた基本的なjQuery Webページから正しいユーザー名を取得してセッションを開始しました。/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; 
    } 
} 

これは、それが可能私はGlassFishの上に配備するJava EE 6アプリケーションにAngularJSからの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); 
      }); 
    }; 
}; 

そして、別のコントローラで

:私はwithCredentialsを設定しようとした

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

$http.defaults.withCredentials = true; 

しかしこれは私の問題を解決していなかった事実です。私もconfigパラメータですべての要求と一緒に送信しようとしましたが、これは私の問題を解決しませんでした。

答えて

19

AngularJSのバージョンによっては、$ httpごとに設定する必要があります。

を行うことができます1.2ので:あなたは角の古いバージョンを使用している場合は、configオブジェクトを渡してみてください

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

:あなたがグローバルに設定することができます1.1.1から

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

withCredentialsを指定する$ httpに設定します。それは1より前のバージョンではうまくいくはずです。1:

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

関連項目の回答とmruelans:私たちが今に設定することができ

5

anwserを@iweinするだけの更新を、設定自体

(唯一の不安定なバージョンの後に利用可能:1.1.1)
config(['$httpProvider', function($httpProvider) { 
    $httpProvider.defaults.withCredentials = true; 
}]). 

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

+0

非常に便利な追加+1 – iwein

5

1.2のバージョンでは、これは私のために動作しません:

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

私はドキュメントを読めば、ショートカットメソッドは、configオブジェクトを取る必要があります

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

$ httpはシングルトンですこれは、資格情報の有無にかかわらず同じアプリケーションリクエストで混在させる唯一の方法です。

+0

ありがとう、彼らはそのAPIを変更し続けるこの –

+0

を追加していただきありがとうございます... – iwein

関連する問題