1

I am building a web app on EC2 instance using Angular and Flask. I am using Apache Tomcat to serve the static HTML files. Tomcat is listening on port 8080. When a login.html page is first loaded, a createState endpoint on Flask app is invoked and this function is supposed to set a cookie on the browser. I can see that the request is received by the Flask app, but the cookies are not set on the browser. However, I can see the cookies when the createState is invoked using postman api tester. Below are the relevant code snippets.

createState endpoint:

@app.route("/createState", methods=["GET", "OPTIONS"])
# Allow cross domain requests from all domains
@cors.crossdomain(origin='*')
def createState():
        state = hashlib.sha256(os.urandom(1024)).hexdigest()
        session["state"] = state
        print("created state token")
        return jsonify(1)

App run section:

if __name__ == "__main__":
        app.config['SESSION_COOKIE_NAME'] = 'weatherSess'
        app.config['SECRET_KEY'] = os.urandom(24)
        app.config['SERVER_NAME'] = "publicDNSofEC2instance:5000"
        app.config['PERMANENT_SESSION_LIFETIME'] = 1800
        # ------------- Any code other than run goes above this line ---------------#
        app.run(host="publicDNSofEC2instance", port=5000, debug=True)
        # host is the same as SERVER_NAME(excluding the port number)

AngularJS call to the createState:

 var login = angular .module("authModule",[])
                .controller("loginController", function($scope, $http, $window, $sce){
                        $scope.user = {};
                        $scope.loginMessage = "";
                        $http({
                                method : "GET",
                                url : instanceURL + "createState"
                        })
                        .then(function(response){
                            // This is a success callback and will be called for status 200-299
                            console.log(response.data);
                            if (response.data) {
                                    if(response.data!==1){
                                        $scope.loginMessage = "Sorry. Internal server error."
                                    }
                            } else {
                                    $scope.loginMessage = "Sorry. Internal server error.";
                                    $scope.user = {};
                            }
                        },
                        function(response){
                            // This is a failure callback
                            $scope.loginMessage = "Oops something went wrong. Please try after sometime.";
                        });

I have tried on chrome, firefox and edge browsers. No luck. Can anyone help me. Oh yeah.. And I even tried using the set_cookie method. It doesn't work either. Any help is much appreciated.

EDIT: So I have just realized that there are probably some issues with the way I am handling the http requests in AngularJS. As I said, I dont see the cookies being set on my browser even after the create state is invoked. But, when I access the endpoint(publicDNSofEC2instance:5000/createState) directly in the URL bar of the browser and then reload the login.html page, I can see the cookies in the browser.

The idea is that the http call should happen as soon as the page is loaded and the cookie should be set. (I have tried removing this http call and setting the cookie based on a button click from Angular, but that did not work either.) Any idea, what I am doing wrong..?

Vikas
  • 1,900
  • 1
  • 19
  • 20
  • So, you've tried the method described in [this snippet](http://flask.pocoo.org/snippets/30/) ? Note that you have to return the response object you set the cookie on. – sytech Oct 21 '16 at 05:28
  • @sytech.. Yes... I have tried it. To make sure that it is not a problem with sessions package, I have added a test cookie using this approach alongside the code I mentioned in the question. Both worked fine with postman, but not when paired with the angular code. – Vikas Oct 21 '16 at 07:33

1 Answers1

0
MyModule.config(function ($httpProvider) {
    $httpProvider.defaults.withCredentials = true;
});

The above lines solved the issue for me. So all this time, the issue was that the $http module in Angular by default does not store the cookies in the response nor does it send cookies to the server. To change that behavior this flag needs to be set.

However, you may also need to disable the

HTTPONLY

flag on your cookie and use a valid domain name for the header

Access-Control-Allow-Origin

instead of a wild card '*'.

Refer to : $http doesn't send cookie in Requests

Community
  • 1
  • 1
Vikas
  • 1,900
  • 1
  • 19
  • 20