我如何使用js客户端将一些方法执行到需要身份验证的Flask restful api中

时间:2015-03-08 22:36:20

标签: javascript ajax rest authentication flask

所以,我正在为Flask restfull api创建一个简单的js客户端应用程序端 我有一些方法需要用户身份验证,但即使我登录服务器我也无法调用它们,获取401错误,未经授权。

这些是登录到烧瓶服务器的代码。

身份验证方法,我保存用户。

@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)

身份验证视图(发布请求)

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客户端(登录功能)Ajax发布请求

    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!");
        });

    }

当我登录服务器时,我无法执行这些功能

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

我在这个ajax电话上获得了401

        $.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");
        });

资源

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和Http响应标题

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 个答案:

答案 0 :(得分:0)

这是因为您需要发送Authorization标头,因为该端点受到保护。在本教程中 - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-1/,它使用基本身份验证,登录端点仅用于检查电子邮件和密码是否正确(当客户端应用程序具有登录页面并且需要验证登录凭据是否有用时很有用在将登录凭据保存在客户端存储(如localStorage)之前更正。客户端应用程序仍负责在每个需要身份验证的请求上发送Authorization标头。您将在本教程的第二部分 - http://tutsbucket.com/tutorials/building-a-blog-using-flask-and-angularjs-part-2/

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

它在每个请求上发送Authorization标头。如果您将检查凭据是否存在于客户端存储中,那么会更好,如果它存在,则通过Authorization标头发送。

我建议您先阅读有关基本身份验证的内容。

希望有所帮助。