0

I am bulding an app with an AngularJS frontend and a Flask REST API for the backend.

I am trying to authenticate a resource using AngularJS $http. My Flask backend is very simple and setup with this decorator to handle the CORS.

My basic view code in Flask looks like:

@auth.verify_password
def verify_password(username, password):
    # for now, I just want to see the correct credentials are present
    print 'credentials: %s %s' % (username, password)
    return True

@app.route('/login')
@cross_origin('http:/localhost')
@auth.login_required
def index():
    return jsonify({'auth': str(request.authorization)})

This works in my local dev environment, so that when I do

curl -u myusername:mypassword http://127.0.0.1:5000/login

I get the expected result:

* About to connect() to 127.0.0.1 port 5000 (#0)
*   Trying 127.0.0.1...
* connected
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
* Server auth using Basic with user 'myusername'
> GET /login HTTP/1.1
> Authorization: Basic am9objpoZWxsbw==
> User-Agent: curl/7.26.0
> Host: 127.0.0.1:5000
> Accept: */*
> 
* additional stuff not fine transfer.c:1037: 0 0
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: application/json
< Content-Length: 20
< Access-Control-Allow-Origin: http://localhost
< Access-Control-Allow-Methods: HEAD, OPTIONS, GET
< Access-Control-Max-Age: 21600
< Access-Control-Allow-Credentials: true
< Access-Control-Allow-Headers: authorization
< Vary: Origin
< Server: Werkzeug/0.10.1 Python/2.7.3
< Date: Mon, 09 Mar 2015 17:37:27 GMT
{
  "auth": "{'username': 'myusername', 'password': 'mypass'}"
  * Closing connection #0
}

In my AngularJS app I want to do the same, so I have an authentication service:

myApp

  .service('AuthService', function ($http, $rootScope, $state) {
    return {
      login: function (credentials) {
        console.log('credentials', credentials); // credentials are correct
        return $http
          .get('http://127.0.0.1:5000/login', credentials)
          .then(function (result) {
            // do something
            console.log('result', result);
          });
        },
        ...
     }
  })

I also configure $http:

// CORS
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common["Accept"] = "application/json";
$httpProvider.defaults.headers.common["Content-Type"] = "application/json";

When I examine the request details when using curl I can clearly see the username and password are passed. However, when using AngularJS the request.authorization object in Flask is empty, meaning there are no credentials or they are in the wrong place.

How do I pass the credentials correctly in AngularJS?

7
  • maybe change from 127.0.0.1:5000/login to just /login. i.e. $http.get('/login', credentials).then(....... Commented Mar 9, 2015 at 20:52
  • No, the url is fine. I can test without the server auth and I get the expected results (response=200 + payload). Commented Mar 9, 2015 at 21:07
  • Looks like you aren't setting the authorization header. Usually this is done in an interceptor so that your services don't need to know about it. Commented Mar 9, 2015 at 21:10
  • You can try something like this $http({method : 'POST', url : '/login', data : credentials}). BTW passing credentials should be done in POST requests (best practice I guess :) ) Commented Mar 9, 2015 at 21:11
  • So the authrorization header can be set with: $http.defaults.headers.common.Authorization. Should it contain both the username and password? Commented Mar 9, 2015 at 21:23

1 Answer 1

1

I think you need:

 $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'
Sign up to request clarification or add additional context in comments.

3 Comments

I think you are advocating constructing the Authorization header on the fly and adding the password. This doesn't seem like a good solution, and it doesn't solve the problem. Why do you consider this a good answer? Which docs?
@DarwinTech I just meant to point out that you need an Authorization header with your credentials base64 encoded. I don't know Angular very well, but it appears to me you could make it part of your default config. But, there must also be a way to send the header at run time. The doc I referenced was docs.angularjs.org/api/ng/service/$http I apologize for being brief in my original post. A down vote would have worked just fine.
This part does seem to be part of the issue. Do I need to be encoding my credentials as base64 before the request is made.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.