如何允许用户使用 HTTP 身份验证在 Angularjs 中登录受保护的flask-rest-api? [英] How to allow users to login protected flask-rest-api in Angularjs using HTTP Authentication?

查看:18
本文介绍了如何允许用户使用 HTTP 身份验证在 Angularjs 中登录受保护的flask-rest-api?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我的问题不清楚,请在下面评论.

flask+angularjs 中 REST API 的基本 HTTP 身份验证

我只想登录angularjs中的flask-rest-api,我不知道如何将登录信息(用户名和密码)发送到flask-rest-api.在这个app 登录成功后有一张表,会加载数据.这里我们不使用任何数据库,但用户名和密码硬编码在其余服务器代码中.和用户名=admin"和密码=1234".什么时候可以修改、更新、添加NewData.我从这个博客中获取了这个,这里他们在淘汰赛中使用,我正在尝试使用 Angularjs

登录表单

<div class="modal-body"><form class="form-horizo​​ntal"><div class="control-group"><label class="control-label" for="inputUsername">Username</label><div class="控件"><input ng-model="username" type="text" id="inputUsername" placeholder="用户名">

<div class="control-group"><label class="control-label" for="inputPassword">Password</label><div class="控件"><input ng-model="password" type="password" id="inputPassword" placeholder="密码">

</表单>

<div class="modal-footer"><button ng-click="submitData(username, password)" class="btn btn-primary" data-dismiss="modal" aria-hidden="true">登录</button>

调用登录模型的HTML代码

AngulurJS 代码

REST-API-SERVER

导入六从烧瓶导入烧瓶,jsonify,中止,请求,make_response,url_for,render_template从flask.ext.httpauth 导入HTTPBasicAuthapp = Flask(__name__, static_url_path="")auth = HTTPBasicAuth()@auth.get_passworddef get_password(用户名):如果用户名 == 'admin':返回1234"返回无@auth.error_handler定义未授权():返回 make_response(jsonify({'error': '未经授权的访问'}), 403)@app.errorhandler(400)def bad_request(错误):返回 make_response(jsonify({'error': 'Bad request'}), 400)@app.errorhandler(404)def not_found(错误):返回 make_response(jsonify({'error': 'Not found'}), 404)任务 = [{'id': 1,'title':你'买杂货','描述':你'牛奶,奶酪,比萨,水果,泰诺','完成':错误},{'id': 2,'title': u'Learn Python','描述':你需要在网上找到一个好的 Python 教程','完成':错误}]def make_public_task(task):新任务 = {}对于任务中的字段:如果字段 == 'id':new_task['uri'] = url_for('get_task', task_id=task['id'],_外部=真)别的:新任务[字段] = 任务[字段]返回新任务@app.route('/')@auth.login_required定义索引():返回 render_template('index.html')@app.route('/todo/api/v1.0/tasks', methods=['GET'])@auth.login_requireddef get_tasks():return jsonify({'tasks': [make_public_task(task) for task in tasks]})@app.route('/todo/api/v1.0/tasks/', methods=['GET'])@auth.login_requireddef get_task(task_id):task = [task for task in tasks if task['id'] == task_id]如果 len(task) == 0:中止(404)返回 jsonify({'task': make_public_task(task[0])})@app.route('/todo/api/v1.0/tasks', methods=['POST'])@auth.login_requireddef create_task():如果不是 request.json 或 request.json 中没有title":中止(400)任务 = {'id':任务[-1]['id'] + 1,'title': request.json['title'],'description': request.json.get('description', ""),'完成':错误}任务.附加(任务)返回 jsonify({'task': make_public_task(task)}), 201@app.route('/todo/api/v1.0/tasks/', methods=['PUT'])@auth.login_requireddef update_task(task_id):task = [task for task in tasks if task['id'] == task_id]如果 len(task) == 0:中止(404)如果不是 request.json:中止(400)如果 request.json 中的 'title' 和 \不是 isinstance(request.json['title'], Six.string_types):中止(400)如果 request.json 中的描述"和 \不是 isinstance(request.json['description'], Six.string_types):中止(400)如果 request.json 中的 'done' 和 type(request.json['done']) 不是 bool:中止(400)task[0]['title'] = request.json.get('title', task[0]['title'])task[0]['description'] = request.json.get('description',任务[0]['描述'])task[0]['done'] = request.json.get('done', task[0]['done'])返回 jsonify({'task': make_public_task(task[0])})@app.route('/todo/api/v1.0/tasks/', methods=['DELETE'])@auth.login_requireddef delete_task(task_id):task = [task for task in tasks if task['id'] == task_id]如果 len(task) == 0:中止(404)任务.删除(任务[0])返回 jsonify({'result': True})如果 __name__ == '__main__':应用程序运行(调试=真)

解决方案

从客户端进行基本身份验证的方式是在 HTTP 请求中提供 Authorization: Basic 标头.

编码的用户名:密码以下面描述的特定方式完成:

<块引用>

  1. 用户名和密码组合成一个字符串用户名:密码"
  2. 然后使用 Base64 的 RFC2045-MIME 变体对结果字符串进行编码,但不限于 76 个字符/行[9]

因此修改您的 rest 调用以在您的 Angularjs 代码中包含上面的标题或找到一个库来做到这一点.

正如上面评论中提到的@Boris,请参阅此链接http://jasonwatmore.com/post/2014/05/26/AngularJS-Basic-HTTP-Authentication-Example.aspx 它有很好的 Angular 服务,可以做你想做的事

Guys If My Question is not clear please comment below.

Basic HTTP Authentication for REST API in flask+angularjs

I just want to login to the flask-rest-api in angularjs, I don't know how to send the login info (username and password)to flask-rest-api. In this app There is one table after successfully login and it will load the data. Here we are not using any data-base but username and password is hard-coded in rest-server code. and username="admin" and password="1234". When can modify, update, addNewData. I took this from this blog, here they are using in knockout, I am trying to in Angularjs

Login form

<div id="login" class="modal hide fade" tabindex="=1" role="dialog" aria-labelledby="loginLabel" aria-hidden="true">
        <div class="modal-header">
            <h3 id="loginLabel">Sign In</h3>
        </div>
        <div class="modal-body">
            <form class="form-horizontal">
                <div class="control-group">
                    <label class="control-label" for="inputUsername">Username</label>
                    <div class="controls">
                        <input ng-model="username" type="text" id="inputUsername" placeholder="Username">
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="inputPassword">Password</label>
                    <div class="controls">
                        <input ng-model="password" type="password" id="inputPassword" placeholder="Password">
                    </div>
                </div>
            </form>
        </div>
        <div class="modal-footer">
            <button ng-click="submitData(username, password)" class="btn btn-primary" data-dismiss="modal" aria-hidden="true">Sign In</button>
        </div>
    </div>

HTML Code Which call Login Model

<div class="navbar">
      <div class="navbar-inner">
        <a class="btn" data-toggle="modal" data-target="#login">Login</a>
      </div>
</div>

AngulurJS code

<script>

                    var app = angular.module('myApp', []);
                    app.controller('tasksCtrl', function($scope, $http) {
                        $scope.submitData=function(username, password){
                            var config={
                               params:{
                                   username:username, password:password
                               }
                            };
                        };
                        //$http.get("data.json")
                        $http.get("/todo/api/v1.0/tasks")
                        .success(function(response) {
                            console.log(response.tasks)
                            $scope.tasks = response.tasks;
                        });

                        $scope.editTask = function(task) {
                            $scope.selectedTask = task;
                        };
                        $scope.removeRow = function(task) {
                            $scope.tasks.splice(task, 1);
                        };
                        $scope.addNewTask = function() {
                            //$scope.tasks.push({title :$scope.task1,description: $scope.description1});
                            $scope.tasks.push({title: $scope.task1, description: $scope.description1});
                            $scope.task1 = '';
                            $scope.description1 = '';
                            //   $scope.tasks.push('dhsh');
                        };
                    });    
        </script>

REST-API-SERVER

import six
from flask import Flask, jsonify, abort, request, make_response, url_for, render_template 
from flask.ext.httpauth import HTTPBasicAuth

app = Flask(__name__, static_url_path="")
auth = HTTPBasicAuth()


@auth.get_password
def get_password(username):
    if username == 'admin':
        return '1234'
    return None


@auth.error_handler
def unauthorized():
    return make_response(jsonify({'error': 'Unauthorized access'}), 403)


@app.errorhandler(400)
def bad_request(error):
    return make_response(jsonify({'error': 'Bad request'}), 400)


@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify({'error': 'Not found'}), 404)


tasks = [
    {
        'id': 1,
        'title': u'Buy groceries',
        'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
        'done': False
    },
    {
        'id': 2,
        'title': u'Learn Python',
        'description': u'Need to find a good Python tutorial on the web',
        'done': False
    }
]


def make_public_task(task):
    new_task = {}
    for field in task:
        if field == 'id':
            new_task['uri'] = url_for('get_task', task_id=task['id'],
                                      _external=True)
        else:
            new_task[field] = task[field]
    return new_task

@app.route('/')
@auth.login_required
def index():
   return render_template('index.html')

@app.route('/todo/api/v1.0/tasks', methods=['GET'])
@auth.login_required
def get_tasks():
    return jsonify({'tasks': [make_public_task(task) for task in tasks]})


@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['GET'])
@auth.login_required
def get_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        abort(404)
    return jsonify({'task': make_public_task(task[0])})


@app.route('/todo/api/v1.0/tasks', methods=['POST'])
@auth.login_required
def create_task():
    if not request.json or 'title' not in request.json:
        abort(400)
    task = {
        'id': tasks[-1]['id'] + 1,
        'title': request.json['title'],
        'description': request.json.get('description', ""),
        'done': False
    }
    tasks.append(task)
    return jsonify({'task': make_public_task(task)}), 201


@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['PUT'])
@auth.login_required
def update_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        abort(404)
    if not request.json:
        abort(400)
    if 'title' in request.json and \
            not isinstance(request.json['title'], six.string_types):
        abort(400)
    if 'description' in request.json and \
            not isinstance(request.json['description'], six.string_types):
        abort(400)
    if 'done' in request.json and type(request.json['done']) is not bool:
        abort(400)
    task[0]['title'] = request.json.get('title', task[0]['title'])
    task[0]['description'] = request.json.get('description',
                                              task[0]['description'])
    task[0]['done'] = request.json.get('done', task[0]['done'])
    return jsonify({'task': make_public_task(task[0])})


@app.route('/todo/api/v1.0/tasks/<int:task_id>', methods=['DELETE'])
@auth.login_required
def delete_task(task_id):
    task = [task for task in tasks if task['id'] == task_id]
    if len(task) == 0:
        abort(404)
    tasks.remove(task[0])
    return jsonify({'result': True})


if __name__ == '__main__':
    app.run(debug=True)

解决方案

The way you make basic authentication from client side is by supplying Authorization: Basic <encoded username:password> header in HTTP request.

encoded username:password is done in specific manner described below:

  1. Username and password are combined into a string "username:password"
  2. The resulting string is then encoded using the RFC2045-MIME variant of Base64, except not limited to 76 char/line[9]

So modify your rest calls to include above header in your Angularjs code or find a library to do that.

as @Boris mentioned in comments above, see this link http://jasonwatmore.com/post/2014/05/26/AngularJS-Basic-HTTP-Authentication-Example.aspx it has nice Angular service written to do just what you want

这篇关于如何允许用户使用 HTTP 身份验证在 Angularjs 中登录受保护的flask-rest-api?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
Python最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆