2016-05-19 6 views
1

フラスコに非常に基本的な安らかなAPIを作成していて、@login_requiredデコレータは 'as_view'エラーをスローします。私はそれがデコレータだということを知っている。あらゆる考え/解決策。 Userクラス内でUserMixinとResourceを継承しようとしました。私は、それが継承されているリソースas_viewと関係しているところを読んでいます。重要な場合は、私はフラスコスクリプトを使用してアプリを実行します。おかげでみんな/女の子。以下のコード、コードの下のトレースバックflask_extfulはflask.ext.loginのlogin_requiredデコレータを使用していません

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' 

編集:だから私が代わりにクラス

class ListCronJobs(Resource): 
    @login_required 
    def get(self): 
    cron = CronTab(user=True) 
    cronjobs = [] 
    for line in cron.lines: 
     cronjobs.append(line) 
    return {'data': cronjobs} 
を飾るの取得(自己)の上@login_required配置することによって、問題を修正

新しい問題は、そのリクエスト(curl "http://127.0.0.1:5000/api/listcronjobs" )を取得したときに "message": "サーバーがアクセス権があることを確認できませんでした要求されたURLあなたは(たとえば、不正なパスワード)間違った資格情報を入力のいずれか、またはお使いのブラウザが必要な資格情報を提供する方法を理解していない。」私はこのカール

答えて

0

作業でのauth後

は私が要求を行いますバージョン。

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\[email protected]\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) 

の代わりにカールしてテストを実行している私は、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() 

カールトンを使用してセッションのauthは保持されていなかったので、cronジョブをリストするAPI呼び出しは拒否されました。

+0

答えに作業コードを追加し、できるだけそれを受け入れることを検討してください。 – IanAuld

関連する問題