Hubspot OAuth的自定义flask_dance蓝图缺少令牌错误

时间:2019-01-17 10:10:04

标签: flask oauth-2.0 hubspot

我正在使用以下示例:https://flask-dance.readthedocs.io/en/latest/quickstarts/sqla-multiuser.html

不是使用github蓝图,而是创建自定义蓝图以与Hubspot的OAuth api通信。

当我执行一个简单的request.post时,我得到一个包含访问和请求令牌的响应对象。

使用flask_dance,我无法控制可以找到的表单数据或其发送方式。授权网址已建立,发送给我选择我的门户网站/帐户,但在重定向时它会显示以下警告:

oauthlib.oauth2.rfc6749.errors.MissingTokenError: (missing_token) Missing access token parameter.

我认为令牌所需的表单数据未正确发送,或者我未在响应中找到令牌。我不确定如何解决这个问题。

Hubspot Oauth2.0文档:https://developers.hubspot.com/docs/methods/oauth2/oauth2-quickstart

import sys
from flask import Flask, redirect, url_for, render_template
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm.exc import NoResultFound
from flask_dance.consumer.backend.sqla import OAuthConsumerMixin, SQLAlchemyBackend
from flask_dance.consumer import OAuth2ConsumerBlueprint, oauth_authorized, oauth_error
from flask_login import (
  LoginManager, UserMixin, current_user,
  login_required, login_user, logout_user
)

# setup Flask application
app = Flask(__name__)
app.secret_key = 'secret'
blueprint = OAuth2ConsumerBlueprint(
  "hubspot", __name__,
  client_id="_not_for_you_",
  client_secret="_not_for_you_",
  token_url="https://api.hubapi.com/oauth/v1/token",
  redirect_uri='https://127.0.0.1:5000',
  scope=["contacts"],
  authorization_url='https://app.hubspot.com/oauth/authorize',
)
app.register_blueprint(blueprint, url_prefix="/login")

#setup database models
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///multi.db'
db=SQLAlchemy()

class User(db.Model, UserMixin):
  id = db.Column(db.Integer, primary_key=True)
  username = db.Column(db.String(256), unique=True)
  email = db.Column(db.String(256), unique=True)
  name = db.Column(db.String(256))

class OAuth(OAuthConsumerMixin, db.Model):
    provider_user_id = db.Column(db.String(256), unique=True)
    user_id = db.Column(db.Integer, db.ForeignKey(User.id))
    user = db.relationship(User)

#setup Login Manager
login_manager = LoginManager()
login_manager.login_view = 'hubspot.login'

@login_manager.user_loader
def load_user(user_id):
  return User.query.get(int(user_id))

# setup SQLAlchemy backend
blueprint.backend = SQLAlchemyBackend(OAuth, db.session, user=current_user)

#create/Login Local user on Succesful OAuth Login
@oauth_authorized.connect_via(blueprint)
def hubspot_logged_in(blueprint, token):
  if not token:
      flash("Failed to log in with Hubspot.", category="error")
      return False

  resp = blueprint.session.get("/user")
  if not resp.ok:
      msg = "Failed to fetch user info from Hubpost."
      flash(msg, category="error")
      return False

  hubspot_info = resp.json()
  hubspot_user_id = str(github_info["id"])

  # Find this OAuth token in the database, or create it
  query = OAuth.query.filter_by(
    provider=blueprint.name,
    provider_user_id=hubspot_user_id,
  )
  try:
    oauth = query.one()
  except NoResultFound:
    oauth = Oauth(
      provider=blueprint.name,
      provider_user_id=hubspot_user_id,
      token=token,
    )

  if oauth.user:
    login_user(oauth.user)
    flash("Successfully signed in with Hubspot.")
  else:
    # Create a new local user account for this user
    user = User(
      # Remember that 'email' can be None, if the user declines
      email=Hubspot_info["email"],
      name=hubspot_info["name"],
    )
    oauth.user = user
    db.session.add_all([user, oauth])
    db.session.commit()
    login_user(user)
    flash("Successfully signed in with hubspot")

  #Disable Flask-Dance's default behavior for saving the OAuth token
  return False

#notify on Oauth provider error
@oauth_error.connect_via(blueprint)
def hubspot_error(blueprint, error, error_description=None, error_uri=None):
  msg = (
    "OAuth error from {name}! "
    "error={error} description={description} url={uri}"
  ).format(
    name=blueprint.name,
    error=error,
    description=error_description,
    uri=error_uri,
  )
  flash(msg, category="error")

@app.route("/logout")
@login_required
def logout():
    logout_user()
    flash("You have logged out")
    return redirect(url_for("index"))

@app.route("/")
def index():
    return render_template("home.html")

# hook up extensions to app
db.init_app(app)
login_manager.init_app(app)

if __name__ == "__main__":
    if "--setup" in sys.argv:
        with app.app_context():
            db.create_all()
            db.session.commit()
            print("Database tables created")
    else:
        app.run(debug=True, host='127.0.0.1', port=5000,  
ssl_context='adhoc')

我希望flask_dance使用我的自定义蓝图与集线器通信并检索访问和刷新令牌。

0 个答案:

没有答案