所以我在烧瓶中写了一个非常基本的restful API,并且@login_required装饰器抛出了' as_view'错误。我知道它是装饰者,因为如果我评论它应用程序运行得很好。任何想法/解决方案。我尝试在User类中继承UserMixin和Resource。我读到了与继承的资源as_view有关的地方。如果重要,我使用flask-script来运行应用程序。谢谢你们。下面的代码,代码
下的回溯import json
from flask import Flask, request
from flask_restful import Resource, abort, Api, reqparse
from flask.views import MethodView
from flask.ext.login import LoginManager, UserMixin, login_required, login_user, logout_user, current_user
from lib.mongo import db
from bson.objectid import ObjectId
from crontab import CronTab
app = Flask(__name__)
app.config["SECRET_KEY"] = ''
login_manager = LoginManager()
login_manager.init_app(app)
api = Api(app)
##############################################
##############################################
#######USER CLASS FOR LOGGING IN AND OUT
##############################################
##############################################
class User(UserMixin):
def __init__(self, username, api_key, id, active=True):
self.username = username
self.api_key = api_key
self.id = id
self.active = active
def is_active(self):
account = db.users.find_one({ 'username': self.username, 'api_key': self.api_key})
if account is not None:
if not account['username'] == self.username and account['api_key'] == self.api_key:
self.active = False
else:
self.active = False
return self.active
def is_anonymous(self):
return False
def is_authenticated(self):
return True
def get_id(self):
return str(db.accounts.find_one({ 'username': self.username, 'api_key': self.api_key})['_id'])
@login_manager.user_loader
def load_user(userid):
user_rec = db.accounts.find_one({'_id': ObjectId(userid)})
user = User(user_rec['username'], user_rec['api_key'], user_rec['_id'])
return user
class Auth(Resource):
def get(self):
api_key = request.args.get('api_key', '')
username = request.args.get('username', '')
if username == '':
abort(400, message='username was not provided')
if api_key == '':
abort(400, message='api key was not provided')
account = db.accounts.find_one({'username': username, 'api_key': api_key})
if account:
if account['account_type'] == 'admin':
user = User(username, api_key, account['_id'])
login_user(user)
return {'auth': 'successful', 'status_code': 200}, 200
else:
abort(401, message='you are not an admin')
else:
abort(401, message='could not auth account')
@login_required
class ListCronJobs(Resource):
def get(self):
cron = CronTab(user=True)
cronjobs = []
for line in cron.lines:
cronjobs.append(line)
return {'data': cronjobs}
api.add_resource(Auth, '/api/auth')
api.add_resource(ListCronJobs, '/api/listcronjobs')
if __name__ == '__main__':
app.run(debug=True)
回溯:
File "manage.py", line 2, in <module>
from app import app
File "/Users/user/folder/app/__init__.py", line 90, in <module>
api.add_resource(ListCronJobs, '/ListCronJobs/listcronjobs')
File "/Users/user/folder/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 401, in add_resource
self._register_view(self.app, resource, *urls, **kwargs)
File "/Users/user/folder/venv/lib/python2.7/site-packages/flask_restful/__init__.py", line 441, in _register_view
resource_func = self.output(resource.as_view(endpoint, *resource_class_args,
AttributeError: 'function' object has no attribute 'as_view'
编辑:所以我通过将@login_required置于get(self)之上而不是装饰类
来解决问题class ListCronJobs(Resource):
@login_required
def get(self):
cron = CronTab(user=True)
cronjobs = []
for line in cron.lines:
cronjobs.append(line)
return {'data': cronjobs}
新问题是,当我提出请求时(curl&#34; http://127.0.0.1:5000/api/listcronjobs&#34; )我收到错误:&#34; message&#34;:&#34;服务器无法验证您是否有权访问所请求的URL。您提供了错误的凭据(例如密码错误),或者您的浏览器并不了解如何提供所需的凭据。&#34;
我在使用curl
进行身份验证后发出请求答案 0 :(得分:0)
所以这是工作版。
from flask import Flask, request
from flask_restful import Resource, abort, Api
from flask.ext.login import LoginManager, UserMixin, login_required, login_user#, logout_user, current_user
from lib.mongo import db
from bson.objectid import ObjectId
from crontab import CronTab
app = Flask(__name__)
app.config["SECRET_KEY"] = 'm\\x88\xe2@\xb18\\x82\xa9\x7f\\x84l[G\x8d\xe6N\x8fJl\\x95{\xd2F\\x10'
login_manager = LoginManager()
login_manager.init_app(app)
api = Api(app)
##############################################
##############################################
#######USER CLASS FOR LOGGING IN AND OUT
##############################################
##############################################
class User(UserMixin):
def __init__(self, username, api_key, id, active=True):
self.username = username
self.api_key = api_key
self.id = id
self.active = active
def is_active(self):
account = db.users.find_one({ 'username': self.username, 'api_key': self.api_key})
if account is not None:
if not account['username'] == self.username and account['api_key'] == self.api_key:
self.active = False
else:
self.active = False
return self.active
def is_anonymous(self):
return False
def is_authenticated(self):
return True
def get_id(self):
return str(db.accounts.find_one({ 'username': self.username, 'api_key': self.api_key})['_id'])
@login_manager.user_loader
def load_user(userid):
user_rec = db.accounts.find_one({'_id': ObjectId(userid)})
user = User(user_rec['username'], user_rec['api_key'], user_rec['_id'])
return user
class Auth(Resource):
def get(self):
api_key = request.args.get('api_key', '')
username = request.args.get('username', '')
if username == '':
abort(400, message='username was not provided')
if api_key == '':
abort(400, message='api key was not provided')
account = db.accounts.find_one({'username': username, 'api_key': api_key})
if account:
if account['account_type'] == 'admin':
user = User(username, api_key, account['_id'])
login_user(user)
return {'auth': 'successful', 'status_code': 200}, 200
else:
abort(401, message='you are not an admin')
else:
abort(401, message='could not auth account')
class ListCronJobs(Resource):
@login_required
def get(self):
cron = CronTab(user=True)
cronjobs = []
for line in cron.lines:
cronjobs.append(line)
return {'data': cronjobs}
api.add_resource(Auth, '/api/auth')
api.add_resource(ListCronJobs, '/api/listcronjobs')
if __name__ == '__main__':
app.run(debug=True)
我没有使用curl运行测试,而是使用python的请求模块运行它们并创建了一个会话。
import requests
s = requests.Session()
res = s.get('http://127.0.0.1:5000/api/auth?username=foo&api_key=bar')
print res.json()
res = s.get('http://127.0.0.1:5000/api/listcronjobs')
print res.json()
在会话中使用curl进行身份验证时,没有保留,因此拒绝列出cronjobs的API调用。