Resource Servers¶
Changed in version v1.0.0: We have removed built-in SQLAlchemy integrations.
Protect users resources, so that only the authorized clients with the authorized access token can access the given scope resources.
A resource server can be a different server other than the authorization server. Here is the way to protect your users’ resources:
from flask import jsonify
from authlib.integrations.flask_oauth1 import ResourceProtector, current_credential
# we will define ``query_client``, ``query_token``, and ``exists_nonce`` later.
require_oauth = ResourceProtector(
app, query_client=query_client,
query_token=query_token,
exists_nonce=exists_nonce,
)
# or initialize it lazily
require_oauth = ResourceProtector()
require_oauth.init_app(
app,
query_client=query_client,
query_token=query_token,
exists_nonce=exists_nonce,
)
@app.route('/user')
@require_oauth()
def user_profile():
user = current_credential.user
return jsonify(user)
The current_credential
is a proxy to the Token model you have defined above.
Since there is a user
relationship on the Token model, we can access this
user
with current_credential.user
.
Initialize¶
To initialize ResourceProtector
, we need three functions:
query_client
query_token
exists_nonce
If using SQLAlchemy, the query_client
could be:
def query_client(client_id):
# assuming ``Client`` is the model
return Client.query.filter_by(client_id=client_id).first()
And query_token
would be:
def query_token(client_id, oauth_token):
return TokenCredential.query.filter_by(client_id=client_id, oauth_token=oauth_token).first()
For exists_nonce
, if you are using cache now (as in authorization server), Authlib
has a built-in tool function:
from authlib.integrations.flask_oauth1 import create_exists_nonce_func
exists_nonce = create_exists_nonce_func(cache)
If using database, with SQLAlchemy it would look like:
def exists_nonce(nonce, timestamp, client_id, oauth_token):
q = db.session.query(TimestampNonce.nonce).filter_by(
nonce=nonce,
timestamp=timestamp,
client_id=client_id,
)
if oauth_token:
q = q.filter_by(oauth_token=oauth_token)
rv = q.first()
if rv:
return True
tn = TimestampNonce(
nonce=nonce,
timestamp=timestamp,
client_id=client_id,
oauth_token=oauth_token,
)
db.session.add(tn)
db.session.commit()
return False
MethodView & Flask-Restful¶
You can also use the require_oauth
decorator in flask.views.MethodView
and flask_restful.Resource
:
from flask.views import MethodView
class UserAPI(MethodView):
decorators = [require_oauth()]
from flask_restful import Resource
class UserAPI(Resource):
method_decorators = [require_oauth()]