Flask: token-based authorization - python

I am building a basic app with Flask: it has a unique route that requests just a token authentication, i.e. if the token provided in the headers is correct, then the request is satisfied. To do so, I installed both Flask and Flask-Security. This is a snippet of my app:
from flask import Flask
from flask.ext.security import auth_token_required
from flask.ext.security import Security
app = Flask(__name__)
app.config['SECURITY_TOKEN_AUTHENTICATION_KEY'] = 'mytoken'
security = Security(app)
#app.route('/myurl')
#auth_token_required
def myrequest():
return 'OK'
if __name__ == '__main__':
app.run(debug=True)
I test it by running:
$ curl -H 'Authorization: Token token="mytoken"' localhost:5000/myurl
or even:
$ curl localhost:5000/myurl
However, I get the following error:
Traceback (most recent call last):
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask_security/decorators.py", line 113, in decorated
if _check_token():
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask_security/decorators.py", line 50, in _check_token
header_key = _security.token_authentication_header
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/werkzeug/local.py", line 338, in __getattr__
return getattr(self._get_current_object(), name)
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/werkzeug/local.py", line 297, in _get_current_object
return self.__local()
File "/Users/username/.virtualenvs/my_env/lib/python2.7/site-packages/flask_security/decorators.py", line 24, in <lambda>
_security = LocalProxy(lambda: current_app.extensions['security'])
KeyError: 'security'
Do you know where the error lies? Is it in the app or in some conflicts among the Flask libraries?
EDIT: added Security(app) initialization

user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)

Related

TikTokApi throws an error in Flask but works outside of it

I have a strange problem when using flask + TikTok API that I can't figure out.
I have the following code:
from flask import Flask
from flask_restful import Resource, Api
from TikTokApi import TikTokApi
tikTokApi = TikTokApi()
app = Flask(__name__)
api = Api(app)
#app.errorhandler(404)
def page_not_found(e):
return {'status': 'fail'}, 404
class TikTokProfile(Resource):
def get(self):
profileResponse = tikTokApi.getUserObject('rosiethepygmygoat')
return {'user' : profileResponse}
class TikTokMedia(Resource):
def get(self):
data = tikTokApi.getUserObject('rosiethepygmygoat')
response = tikTokApi.userPage(data["id"],data["secUid"])
return response
api.add_resource(TikTokProfile, '/profile')
api.add_resource(TikTokMedia, '/media')
if __name__ == '__main__':
app.run(debug=True)
When I visit /profile I get the user object, but when I try to get his user page via the /media route I get the following error:
INFO:werkzeug:127.0.0.1 - - [08/Jan/2021 09:20:45] "GET /media HTTP/1.1" 500 -
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 272, in error_router
return original_handler(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 272, in error_router
return original_handler(e)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\_compat.py", line 38, in reraise
raise value.with_traceback(tb)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 468, in wrapper
resp = resource(*args, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask\views.py", line 89, in view
return self.dispatch_request(*args, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\flask_restful\__init__.py", line 583, in dispatch_request
resp = meth(*args, **kwargs)
File "D:\server\norway_group\tokmatic-sass\python\start.py", line 22, in get
response = tikTokApi.userPage(data["id"],data["secUid"])
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\tiktok.py", line 562, in userPage
return self.getData(url=api_url, **kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\tiktok.py", line 159, in getData
verify_fp, did, signature = self.browser.sign_url(**kwargs)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\browser.py", line 164, in sign_url
page = self.create_page()
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\TikTokApi\browser.py", line 116, in create_page
context = self.browser.newContext(**iphone)
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\playwright\sync_api.py", line 6710, in newContext
self._sync(
File "C:\Users\user\AppData\Local\Programs\Python\Python38-32\Lib\site-packages\playwright\_sync_base.py", line 95, in _sync
self._dispatcher_fiber.switch()
greenlet.error: cannot switch to a different thread
I thought that there is an issue with the TikTokApi package but when I try the same code outside the flask resource:
data = tikTokApi.getUserObject('rosiethepygmygoat')
response = tikTokApi.userPage(data["id"],data["secUid"])
print(response)
I get the object I need.
So am I missing a specific configuration for flask or something else? Any insights will be much appreciated.
Run your flask application using this comands:
flask run --without-threads

#jwt_required decorator not working on flask endpoint

I have a Flask Blueprint endpoint, defined as:
from flask_jwt import JWT, jwt_required, current_identity
my_api = Blueprint('MyApi', __name__)
#my_api.route("/MyApi", methods=['GET'])
#jwt_required()
def get_my_api():
return make_response()
I have JWT configuration done in main API configuration file (other than the file that has the endpoint defined above):
app = Flask(__name__)
app.register_blueprint(my_api)
jwt = JWTManager(app)
So even though I am able to generate access_token and refresh_token but upon hitting the decorator jwt_required, I get this exception:
File "/home/lib/python3.6/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/home/lib/python3.6/site-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/lib/python3.6/site-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/lib/python3.6/site-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/home/lib/python3.6/site-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/lib/python3.6/site-packages/flask_jwt/__init__.py", line 177, in decorator
_jwt_required(realm or current_app.config['JWT_DEFAULT_REALM'])
File "/home/lib/python3.6/site-packages/flask_jwt/__init__.py", line 152, in _jwt_required
token = _jwt.request_callback()
File "/home/lib/python3.6/site-packages/werkzeug/local.py", line 348, in __getattr__
return getattr(self._get_current_object(), name)
File "/home/lib/python3.6/site-packages/werkzeug/local.py", line 307, in _get_current_object
return self.__local()
File "/home/lib/python3.6/site-packages/flask_jwt/__init__.py", line 28, in <lambda>
_jwt = LocalProxy(lambda: current_app.extensions['jwt'])
KeyError: 'jwt'
Am I doing something wrong? Thanks.
It looks like you are mixing two different extensions. from flask_jwt import JWT, jwt_required, current_identity is the flask-jwt extension, and the jwt = JWTManager(app) is flask-jwt-extended extension. Flask-jwt has been abandoned for a long time now, so I would recommend using flask-jwt-extended in your codebase: https://flask-jwt-extended.readthedocs.io/en/stable/basic_usage.html

Getting error Client sent AUTH, but no password is set while initializing Redis object

I am fairly new to redis and using configuring redis with flask app.
i have edited redis.conf file and uncommented requirepass
requirepass foobared
and I am able to get into redid-cli using this password.
like this ./redis-cli -h 127.0.0.1 -p 6379 -a foobared
but when I try to initialise an object of Redis class by passing in the password,
>>> import os
>>> import redis
>>> from flask import Flask
>>> from redis import Redis
>>> app = Flask('weatherApp')
>>> app.config["REDIS_HOST"] = os.getenv("REDIS_HOST")
>>> app.config["REDIS_PORT"] = os.getenv("REDIS_PORT")
>>> app.config["REDIS_PWD"] = os.getenv("REDIS_PWD")
>>> app
<Flask 'weatherApp'>
>>> app.config
>>> redis = Redis(app.config["REDIS_HOST"], port=app.config["REDIS_PORT"],
... db=0, password=app.config["REDIS_PWD"])
>>> redis.client_list()
I keep getting the error saying:
Traceback (most recent call last):
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 2000, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/Users/ciasto-piekarz/Development/web/python/weatherApp/src/views.py", line 192, in dispatch_request
print redis.client_list()
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/client.py", line 703, in client_list
return self.execute_command('CLIENT LIST')
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/client.py", line 667, in execute_command
connection.send_command(*args)
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/connection.py", line 610, in send_command
self.send_packed_command(self.pack_command(*args))
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/connection.py", line 585, in send_packed_command
self.connect()
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/connection.py", line 493, in connect
self.on_connect()
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/connection.py", line 561, in on_connect
if nativestr(self.read_response()) != 'OK':
File "/Users/ciasto-piekarz/Development/web/python/flask/flsk-dimnd/venv/lib/python2.7/site-packages/redis/connection.py", line 629, in read_response
raise response
ResponseError: Client sent AUTH, but no password is set
Any help will be greatly appreciated!

How do I configure a Flask app inside a Docker container to parse a large MessagePack object?

I'm getting the following when sending a very large POST to a Flask application.
Logs:
restful stderr | /usr/local/lib/python2.7/dist-packages/werkzeug/filesystem.py:63: BrokenFilesystemWarning: Detected a misconfigured UNIX filesystem: Will use UTF-8 as filesystem encoding instead of 'ANSI_X3.4-1968'
BrokenFilesystemWarning)
restful stderr | 172.19.0.5 - - [25/Apr/2017 00:05:40] "POST /ml/source/ HTTP/1.1" 500 -
restful stderr | Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/opt/fish/bizco/ml/restful.py", line 49, in index
job = q.enqueue_call(func=process_request, args=(postObject,), result_ttl=5000, timeout=36000)
File "/usr/local/lib/python2.7/dist-packages/rq/queue.py", line 216, in enqueue_call
job = self.enqueue_job(job, at_front=at_front)
File "/usr/local/lib/python2.7/dist-packages/rq/queue.py", line 282, in enqueue_job
pipe.execute()
File "/usr/local/lib/python2.7/dist-packages/redis/client.py", line 2641, in execute
return execute(conn, stack, raise_on_error)
File "/usr/local/lib/python2.7/dist-packages/redis/client.py", line 2495, in _execute_transaction
connection.send_packed_command(all_cmds)
File "/usr/local/lib/python2.7/dist-packages/redis/connection.py", line 556, in send_packed_command
(errno, errmsg))
ConnectionError: Error 104 while writing to socket. Connection reset by peer.
Route Code:
#app.route('/zebra/', methods=['GET', 'POST'])
def index():
print "/zebra/ called:")
if request.method == "POST":
state = True
if request.headers['Content-Type'] == 'application/x-msgpack':
print 'Found MsgPack'
postObject = msgpack.unpackb(request.data)
else:
print 'Content type not correct'
state = False
if state == True:
json = jsonify(...)
else:
# return an error
json = jsonify...)
return json
The POST object contains a MessagePack encoded payload, but it never enters my route handler. I see no log statement inside the handler block.
This only seems to happen when the payload is above 200MB. How do I get flask to store handle properly?

Its Dangerous creating a token: cannot concatenate 'str' and 'NoneType' objects

I have an email confirmation feature on my Flask application. For this to work, I must create a token which will go in a confirmation link. To create the token I'm using Its Dangerous like so:
from itsdangerous import URLSafeTimedSerializer
ts = URLSafeTimedSerializer(app.config["SECRET_KEY"])
token = ts.dumps(email, salt='email-confirm-key')
confirm = url_for('confirm', token=token, _external=True)
After running this, I receive an error stating cannot concatenate 'str' and 'NoneType' objects from the following traceback:
Traceback (most recent call last):
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/pavsidhu/Documents/Web-Development/myapp/myapp/views/confirmation.py", line 62, in resend
activateEmail(email)
File "/Users/pavsidhu/Documents/Web-Development/myapp/myapp/views/functions.py", line 34, in activateEmail
token = ts.dumps(email, salt='email-confirm-key')
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/itsdangerous.py", line 566, in dumps
rv = self.make_signer(salt).sign(payload)
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/itsdangerous.py", line 412, in sign
return value + sep + self.get_signature(value)
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/itsdangerous.py", line 347, in get_signature
key = self.derive_key()
File "/Users/pavsidhu/Documents/Web-Development/myapp/env/lib/python2.7/site-packages/itsdangerous.py", line 334, in derive_key
self.secret_key).digest()
TypeError: cannot concatenate 'str' and 'NoneType' objects
I'm unsure what the issue is, as email is a string and the salt is one too. What could be the problem? Thanks.
The issue is this line:
ts = URLSafeTimedSerializer(app.config["SECRET_KEY"])
It looks like your app.config["SECRET_KEY"] is not being set correctly. If you replace that line with this
ts = URLSafeTimedSerializer('test')
You should find that it works. So you need to find out why app.config["SECRET_KEY"] is not being set correctly.

Categories

Resources