0

So, I'm creating a simple js client app side to a Flask restfull api I Have some methods that needs user authentication, but even if I Log into the server I Cannot call them, Get 401 error, Unauthorized.

these are the codes from the login into the flask server.

Authentication method, where I save the user.

@auth.verify_password
def verify_password(email, password):
    user = User.query.filter_by(email=email).first()
    if not user:
        return False
    g.user = user
    return flask_bcrypt.check_password_hash(user.password, password)

Authentication View(Post Request)

class SessionView(restful.Resource):
    def post(self):
        form = SessionCreateForm()
        if not form.validate_on_submit():
            return form.errors, 422

        user = User.query.filter_by(email=form.email.data).first()
        if user and flask_bcrypt.check_password_hash(user.password, form.password.data):
            return UserSerializer(user).data, 201
        return '', 401

SessionForm

class SessionCreateForm(Form):
    email = StringField('email', validators=[DataRequired()])
    password = StringField('password', validators=[DataRequired()])

JS Client(login function) Ajax post request

    function logar () {

        var lform = $('#loginform').serializeArray();

        login = lform[0].value;
        password = lform[1].value;

        $.ajax
        ({  
            type: "POST",
            url: "http://localhost:5000/api/v1/sessions",
            data: {email: login, password: password},
        })
        .success(function(result)
        {
            // logou
            $.cookie("user", login);

            console.log(result);

            window.location.replace("index.html");
        })
        .error(function(result)
        {
            alert("Not Authorized!");
        });

    }

and when I'm logged into the server I cannot execute these functions

class PurchaseView(restful.Resource):
    @auth.login_required
    def post(self):
        form = PurchaseCreateForm()
        if not form.validate_on_submit():
            return form.errors, 422
        purchase = Purchase(form.total.data)

        g.purchase = purchase

        db.session.add(purchase)
        db.session.commit()
        return PurchaseSerializer(purchase).data, 201

I get 401 on this ajax call

        $.ajax
        ({
            type: "POST",
            url: "http://localhost:5000/api/v1/purchase",
            data: {total: cart.total},
        })
        .success(function(result)
        {
            console.log(result);

        })
        .error(function(result)
        {
            alert("Error");
        });

resources

api.add_resource(UserView, '/api/v1/users')
api.add_resource(SessionView, '/api/v1/sessions')
api.add_resource(ProductListView, '/api/v1/products')
api.add_resource(ProductUpdateView, '/api/v1/product_update')
api.add_resource(PurchaseProductView, '/api/v1/purchase_product')
api.add_resource(PurchaseView, '/api/v1/purchase')
api.add_resource(ProductView, '/api/v1/products/<int:id>')

curl and Http response header

curl 'http://localhost:5000/api/v1/purchase' -H 'Origin: http://localhost:8000' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.8,es;q=0.6,pt;q=0.4' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: http://localhost:8000/checkout.html' -H 'Connection: keep-alive' --data 'total=40' --compressed


HTTP/1.0 401 UNAUTHORIZED
Content-Type: text/html; charset=utf-8
Content-Length: 19
WWW-Authenticate: Basic realm="Authentication Required"
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type,Authorization
Access-Control-Allow-Methods: GET,PUT,POST,DELETE
Server: Werkzeug/0.9.6 Python/2.7.6
Date: Mon, 09 Mar 2015 03:09:44 GMT

1 Answer 1

0

It's because you need to send the Authorization header because that endpoint is protected. In this tutorial - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-1/ , it uses basic authentication and the login endpoint is only used for checking if the email and password is correct (Useful when your client application has a login page and it needs to verify that the login credentials are correct before it saves the login credentials in the client-side storage like localStorage). The client application is still responsible for sending the Authorization header on every request that needs authentication. You'll see in the second part of the tutorial - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-2/

headers['Authorization'] = 'Basic ' + AuthService.getToken();

that it sends the Authorization header on every request. Would be better if you will check if the credentials are present in the client side storage then if it's present, send it via the Authorization header.

I recommend that you read about Basic authentication first.

Hope that helps.

Sign up to request clarification or add additional context in comments.

1 Comment

So, there's a way to return the authToken trough the server app?

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.