最新消息:20190717 VPS服务器:Vultr新加坡,WordPress主题:大前端D8,统一介绍入口:关于

[记录]如何在Flask中实现记住微信公众号的用户帐户的登录状态

Flask crifan 1006浏览 0评论

之前已经:

[基本解决]尝试去搞清楚微信网页授权后如何保持用户登录状态

现在需要在,微信后台服务器,Flask中,记住微信用户的登录状态

尤其是此处的

对于一个活动页面,地址被分享出去后,如何在别的用户,

在微信环境下,点击对应的页面链接,进入该页面

如何自动判断:

如果之前用户已经登录后,就无需再登录

如果之前没有登录过,就需要授权登录

另外,如果方便的话,也要去:

判断该微信的账号,是否是已经关注了此处对应的微信公众号

对于没有关注的,如何判断出来,如何处理

对于已关注的,则允许继续操作,比如允许点击关注去关注对应的活动

微信 保持登录 如何

flask 微信 保持登录 如何

关于 python-flask 的上下文功能 在微信(浏览器)中保存 用户会话 的问题 – V2EX

->

用openid和oauth

Flask-OpenID — Flask-OpenID

Flask-OAuth — Flask-OAuth

Flask-OpenID — Flask-OpenID

Python的Flask框架中实现简单的登录功能的教程 – 新客网

使用Flask-OAuthlib实现QQ OAuth2登录 – digwtx – SegmentFault

flask 微信 保持登录 session

flask貌似没有cookies,怎么保存登录状态?

Flask web开发 处理Session – 互联网 – IT610.com

“上面的代码,与前面相比。在test请求的响应处理中,判断session中是否存在username,不存在就跳转到login页面,并把test地址在session中保存。

然后在login的post请求中,检查newurl是否存在,存在的话表示是由别的页面跳转到登录页面的,这样登录成功后跳转到相应页面,缺省是跳转到home页面。”

Flask的session

你会做Web上的用户登录功能吗? | 酷 壳 – CoolShell.cn

-》好像可以利用:FLask-Login

-》未必需要单独显示帐号和密码的登录框,

而是页面跳转到微信授权页面?

flask 微信 login_required

Flask-Login — Flask-Login 0.3.2 documentation

记录一次使用Flask开发过程中的bug – 寻寻觅觅 – SegmentFault

Flask学习记录之Flask-Login – agmcs – 博客园

View Decorators — Flask Documentation (0.11)

flask 微信 Flask-Login

flask 微信公众号 登录 Flask-Login

python – 新手学习Flask引用flask-login后登入错误原因不清 – SegmentFault

flask笔记:6:用户登入登出

Flask-Login — Flask-Login 0.3.2 documentation

“用户对象助手

class flask.ext.login.UserMixin[source]

This provides default implementations for the methods that Flask-Login expects user objects to have.”

(SIPEvents) ➜  SIPEvents pip install Flask-Login
Collecting Flask-Login
  Downloading Flask-Login-0.3.2.tar.gz
Requirement already satisfied (use –upgrade to upgrade): Flask in /root/Envs/SIPEvents/lib/python2.7/site-packages (from Flask-Login)
Requirement already satisfied (use –upgrade to upgrade): itsdangerous>=0.21 in /root/Envs/SIPEvents/lib/python2.7/site-packages (from Flask->Flask-Login)
Requirement already satisfied (use –upgrade to upgrade): Jinja2>=2.4 in /root/Envs/SIPEvents/lib/python2.7/site-packages (from Flask->Flask-Login)
Requirement already satisfied (use –upgrade to upgrade): Werkzeug>=0.7 in /root/Envs/SIPEvents/lib/python2.7/site-packages (from Flask->Flask-Login)
Requirement already satisfied (use –upgrade to upgrade): click>=2.0 in /root/Envs/SIPEvents/lib/python2.7/site-packages (from Flask->Flask-Login)
Requirement already satisfied (use –upgrade to upgrade): MarkupSafe in /root/Envs/SIPEvents/lib/python2.7/site-packages (from Jinja2>=2.4->Flask->Flask-Login)
Building wheels for collected packages: Flask-Login
  Running setup.py bdist_wheel for Flask-Login … done
  Stored in directory: /root/.cache/pip/wheels/87/fe/9e/b88482e88c4cc95c91614eb13225740b4d9e21f1fbcd098b58
Successfully built Flask-Login
Installing collected packages: Flask-Login
Successfully installed Flask-Login-0.3.2

然后去参考一堆的帖子,去试试。

[已解决]Flask-Login运行出错:AttributeError _AppCtxGlobals object has no attribute user

至此,终于搞懂了逻辑了。

整理如下:

想要使用Flask-Login的整套步骤和内部所涉及到的逻辑。

1.安装Flask-Login

这个最简单:

(在虚拟环境中,去安装即可)

pip install Flask-Login

2.按照官网教程和其他人的教程:

Flask-Login — Flask-Login 0.3.2 documentation

(英文:Flask-Login — Flask-Login 0.3.2 documentation

View Decorators — Flask Documentation (0.11)

Flask学习记录之Flask-Login – agmcs – 博客园

flask笔记:6:用户登入登出

著名的那个教程:

The Flask Mega-Tutorial, Part V: User Logins – miguelgrinberg.com

如果涉及到blueprint则参考:

使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(三)——使用Flask-Login库实现登录功能 – 博客吧

[总结]

使用Flask-Login去实现微信授权登录后才能访问某些接口的整套方法:

(1)初始化LoginManager

在:

/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/flask/sipevents/__init__.py

添加了对应的初始化LoginManager的代码:

from flask_login import LoginManager
loginManager = LoginManager()
loginManager.init_app(app)
#可以设置None,’basic’,’strong’  以提供不同的安全等级,一般设置strong,如果发现异常会登出用户
loginManager.session_protection = ‘strong’
loginManager.login_view = ‘login’ #登陆界面的路由
loginManager.login_message = u”请进行微信授权登录以访问此页面”
# loginManager.login_message_category = “info”
gLog.debug(“type(loginManager)=%s, loginManager=%s”, type(loginManager), loginManager)
# type(loginManager)=<class ‘flask_login.LoginManager’>, loginManager=<flask_login.LoginManager object at 0x7f5c27476f10>

(2)给已有的用户User添加对应的属性

/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/flask/sipevents/models.py

class User(db.Model):
    __tablename__ = ‘wechat_users’
    # Columns
    openid = db.Column(db.String(64), primary_key=True, nullable=False)
    province = db.Column(db.String(16))
    avatar_url = db.Column(db.String(256))
    avatar_static_path = db.Column(db.String(256))
    language = db.Column(db.String(8))
    city = db.Column(db.String(16))
    country = db.Column(db.String(32))
    sex = db.Column(db.SmallInteger)
    nickname = db.Column(db.String(128))
    events = db.relationship(‘Event’, backref = ‘creator’, lazy = ‘dynamic’)
    # is_authenticated 允许用户验证,只返回True
    def is_authenticated(self):
        return True
    # is_active 有效账户都返回True,除非禁止账户
    def is_active(self):
        return True
    # is_anonymous 伪造用户之外都是True
    def is_anonymous(self):
        return False
    # get_id 返回用户唯一标识符,以unicode格式
    def get_id(self):
        try:
            return unicode(self.openid)  # python 2
        except NameError:
            return str(self.openid)  # python 3
    def __init__(self,
                 openid,
                 province = “”,
                 avatar_url = “”,
                 avatar_static_path = “”,
                 language = “”,
                 city = “”,
                 country = “”,
                 sex = 0,
                 nickname = “”):
        self.openid     = openid
        self.province   = province
        self.avatar_url = avatar_url
        self.avatar_static_path = avatar_static_path
        self.language   = language
        self.city       = city
        self.country    = country
        self.sex        = sex
        self.nickname   = nickname
    def __repr__(self):
        #return u'<User %r %s>’ % (self.nickname, self.openid)
        return ‘<User nickname=%r openid=%s avatar_static_path=%s>’ % (self.nickname, self.openid, self.avatar_static_path)

其中:

  • is_authenticated:这个名字起的容易让人误解,实际上的含义是:是否允许认证,is_allow_authenticate,不是:是否已经认证了==是否已经登录了
  • is_active
  • is_anonymous
  • get_id

是新添加的。

注:

如果你的User中的id是Integer这种:

id = db.Column(db.Integer, primary_key=True)

那么可以直接借用,官网自带的,已经帮你实现了对应的各个额外的上述方法:

from flask.ext.login import UserMixin
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    。。。

此处的UserMixin会自动帮你给已有的User添加上:

  • is_authenticated
  • is_active
  • is_anonymous
  • get_id

就不用你自己去实现了。

(3)view中的各种路由,各种逻辑

/Users/crifan/dev/dev_root/daryun/SIPEvents/sourcecode/flask/sipevents/views.py

############################################################
# Flask-Login
############################################################
from functools import wraps
# from flask_login import login_required
from flask_login import login_user, logout_user
from flask_login import current_user
from . import app, gLog, loginManager
#from YOUR_APP_NAME import app, gLog, loginManager
import urllib
############################################################
# app related
############################################################
@app.before_request
def before_request():
    “””
    这里是全局的方法,在请求开始之前调用。
    其中 flask 有个全局的变量 g,它是和 session 一样的用途,可以使用它来保存当前用户的数据
    Returns:
    “””
    if current_user.is_authenticated:
        g.user = current_user
    else:
        g.user = None
    gLog.debug(“g=%s, g.user=%s, current_user=%s”, g, g.user, current_user)
    # g=<flask.g of ‘sipevents’>, g.user=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>, current_user=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>
    pass
@loginManager.user_loader
def load_user(userOpenid):
    gLog.debug(“type(userOpenid)=%s, userOpenid=%s”, type(userOpenid), userOpenid)
    # type(userOpenid)=<type ‘unicode’>, userOpenid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc
    loadedUser = getUserInfo(userOpenid)
    gLog.debug(“loadedUser=%s”, loadedUser)
    # loadedUser=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>
    return loadedUser
@app.route(“/login”)
def login():
    requestArgs = request.args
    gLog.debug(‘requestArgs=%s’, requestArgs)
    # requestArgs=ImmutableMultiDict([(‘next’, u’http://hd.webonn.com/’)])
    nextRedirectUrl = requestArgs.get(“next”, “”)
    gLog.debug(“nextRedirectUrl=%s”, nextRedirectUrl)
    return redirect(url_for(“wechat_auth”, nextRedirectUrl=nextRedirectUrl))
#@app.route(“/wechat_auth”, methods=[‘GET’, ‘POST’])
@app.route(“/wechat_auth”)
def wechat_auth():
    requestArgs = request.args
    gLog.debug(‘requestArgs=%s’, requestArgs)
    nextRedirectUrl = request.args.get(“nextRedirectUrl”, “”)
    gLog.debug(‘nextRedirectUrl=%s’, nextRedirectUrl)
    needRedirect = False
    paraCode = request.args.get(‘code’, ”)
    gLog.debug(‘paraCode=%s’, paraCode)
    if not paraCode:
        needRedirect = True
    paraState = request.args.get(‘state’, ”)
    gLog.debug(‘paraState=%s’, paraState)
    # if not paraState :
    #     needRedirect = True
    gLog.debug(‘needRedirect=%s’, needRedirect)
    if needRedirect:
        # 1. redirect url
        quotedNextRedirectUrl = urllib.quote(nextRedirectUrl)
        gLog.debug(“quotedNextRedirectUrl=%s”, quotedNextRedirectUrl)
        redirectUri = “%s/wechat_auth?nextRedirectUrl=%s” % (BASE_URL, quotedNextRedirectUrl)
        authorizeUrl = wechat.generate_oauth2_authorize_url(redirectUri)
        gLog.debug(‘redirectUri=%s, authorizeUrl=%s’, redirectUri, authorizeUrl)
        # redirectUri=http://hd.webonn.com/wechat_auth
        # authorizeUrl=https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9xxxxxxxxxxxxxxd&redirect_uri=http%3A//hd.webonn.com/wechat_auth&response_type=code&scope=snsapi_userinfo&state=#wechat_redirect
        gLog.info(“for wechat auth, redirect to %s”, authorizeUrl)
        return redirect(authorizeUrl)
    else:
        # 2. get access token
        respAccessToken = wechat.get_oauth2_access_token(paraCode)
        gLog.debug(‘respAccessToken=%s’, respAccessToken)
        # respAccessToken={u’access_token’: u’5Lnjm56ox1djVEFEIAdvp4HdcHVO1WsEWCDXVIS0zLZc3veMB4KXLMu843h_MpLJ6xLjlHGeclhhhSsErowWCeFMBMC3CbWX4zDezvu_D7M’, u’openid’: u’oswxxxxxxxxxxxxxxxxxxxxxxVVY’ u’expires_in’: 7200, u’refresh_token’: u’QE-prEWTMHrDBqZGcJLYOg5fNqvpVL6qrp2YekXlyWq2agtwsGhO5IIxujpIBwXzUMy80n7d9xiWFZEwrNt10ilFpRkTbwP4cBzQ2df7eUw’, u’scope’: u’snsapi_userinfo’}
        respAccessTokenStr = jsonToStr(respAccessToken)
        gLog.debug(‘respAccessTokenStr=%s’, respAccessTokenStr)
        # respAccessTokenStr = {
        #     “access_token”: “K8EMRg7DTYnElLOgLix0yVIKeSg85KWmChnGK4PZ8T5N2EiHevQZEm6hyMBPfkOh5Hl3r0H_koLFmHuMFuGOXoyLMn-A7IT0ztqPKvi6TIY”,
        #     “openid”: “oswxxxxxxxxxxxxxxxxxxxxxxVVY”,
        #     “expires_in”: 7200,
        #     “refresh_token”: “wWfqaQyxbAK4WUKwmPeTuSQ7_Nlnxz35xAZ5fu6ZlQseR526zKyemwA7YozbUmbGYSETIpGCi0T-HXMhgKXKVvi5Kon2_4_uWAwhNcxCRBI”,
        #     “scope”: “snsapi_userinfo”
        # }
        oauth2Access_token = respAccessToken[‘access_token’]
        oauth2Openid = respAccessToken[‘openid’]
        gLog.debug(‘oauth2Access_token=%s, oauth2Openid=%s’, oauth2Access_token, oauth2Openid)
        respUserInfoDict = wechat.get_oauth2_userinfo(oauth2Access_token, oauth2Openid)
        gLog.debug(‘type(respUserInfoDict)=%s, respUserInfoDict=%s’, type(respUserInfoDict), respUserInfoDict)
        # type(respUserInfoDict) = < type ‘dict’ >, respUserInfoDict = {u’province’: u’\xe6\xb1\x9f\xe8\x8b\x8f’,
        #                               u’openid’: u’oswxxxxxxxxxxxxxxxxxxxxxxVVY’,
        #                               u’headimgurl’: u’http://wx.qlogo.cn/mmopen/ajNVdqHZLLDYtIJicNl7MjwZK5c1lxAJZ253c9v3JzDib7GeE5OFrWiaRqsK1ruW1HmGaziaYETV5vQhIIbic6wHKFQ/0′,
        #                               u’language’: u’zh_CN’, u’city’: u’\xe8\x8b\x8f\xe5\xb7\x9e’,
        #                               u’country’: u’\xe4\xb8\xad\xe5\x9b\xbd’, u’sex’: 1, u’privilege’: [],
        #                               u’nickname’: u’\xe7\xa4\xbc\xe8\xb2\x8c’}
        curUser = saveUserInfoToDb(respUserInfoDict)
        gLog.debug(“curUser=%s”, curUser)
        gLog.info(“record logged in for user=%s”, curUser)
        login_user(curUser, remember = True) # 第一个参数传入用户对象,第二个参数 传入 以后是否自动登陆
        # flash(u’用户 %s 登录成功’, curUser.nickname)
        gLog.info(“%s logged in succssfully”, curUser)
        #TODO: add redirect url validation
        # next = request.args.get(‘next’)
        # gLog.debug(“next=%s”, next)
        # # next_is_valid should check if the user has valid
        # # permission to access the `next` url
        # if not next_is_valid(next):
        #     gLog.error(“next is invalid, go abort 400”)
        #     return abort(400)
        #return redirect(next or url_for(‘index’))
        if nextRedirectUrl:
            gLog.debug(“after wechat auth, redirect to nextRedirectUrl=%s”, nextRedirectUrl)
            # after wechat auth, redirect to nextRedirectUrl=http://hd.webonn.com/
            return redirect(nextRedirectUrl)
        else:
            gLog.debug(“after wechat auth, redirect to default router: index”)
            return redirect(url_for(“index”))
def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if g.user is None:
            return redirect(url_for(‘login’, next=request.url))
        return f(*args, **kwargs)
    return decorated_function
@app.route(“/index”)
@app.route(“/”)
@login_required
def index():
    requestArgs = request.args
    gLog.debug(‘requestArgs=%s’, requestArgs)
    curUser = g.user
    gLog.debug(“g=%s, curUser=%s”, g, curUser)
    # g=<flask.g of ‘sipevents’>, curUser=<flask_login.AnonymousUserMixin object at 0x7f93ab317390>
    # g=<flask.g of ‘sipevents’>, curUser=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>
    gLog.debug(“curUser=%s”, curUser)
    # curUser=<User nickname=u’\u793c\u8c8c’ openid=oswxxxxxxxxxxxxxxxxxxxxxxVVY avatar_static_path=img/avatar/oswxxxxxxxxxxxxxxxxxxxxxxVVY.png>
    # curUser=<flask_login.AnonymousUserMixin object at 0x7f93ab317390>
    gLog.debug(“type(curUser)=%s”, type(curUser))
    # type(curUser)=<class ‘sipevents.models.User’>
    # type(curUser)=<class ‘werkzeug.local.LocalProxy’>
    # type(curUser)=<class ‘werkzeug.local.LocalProxy’>
    …………..
    return render_template(‘index.html’,
                           curUser = curUser,
                           expiredEventList = expiredEventList,
                           todayEventList = todayEventList,
                           tomorrowEventList = tomorrowEventList,
                           futureEventList = futureEventList)

然后对应的逻辑是:

1./ 之前的 before_request

@app.before_request
def before_request():

用户访问 / 或 /index 之前,会去访问:

before_request

其中会发现,

此时current_user是没有登录的用户,是AnonymousUserMixin

g=<flask.g of ‘sipevents’>, g.user=None, current_user=<flask_login.AnonymousUserMixin object at 0x7f03cd2e9390>

所以此时current_user.is_authenticated为False

所以:

g.user设置为None

2./ 的login_required限定

@app.route(“/index”)
@app.route(“/”)
@login_required
def index():

 用户访问首页 / 或 /index 时,

发现其有对应的限定:

@login_required

所以去访问login_required

中的:decorated_function

        if g.user is None:
            return redirect(url_for(‘login’, next=request.url))

里面去判断,发现:

g.user为None

即,用户还没有登录

所以跳转到:

login

且传入了next参数,值为此处要访问的url

requestArgs=ImmutableMultiDict([(‘next’, u’http://hd.webonn.com/’)])

3.login的

@app.route(“/login”)
def login():

login中,获得next参数给nextRedirectUrl

nextRedirectUrl=http://hd.webonn.com/

然后去,跳转到,负责处理微信授权的wechat_auth

return redirect(url_for(“wechat_auth”, nextRedirectUrl=nextRedirectUrl))

4.进入wechat_auth,此时code为空

@app.route(“/wechat_auth”)
def wechat_auth():

得到了nextRedirectUrl参数:

requestArgs=ImmutableMultiDict([(‘nextRedirectUrl’, u’http://hd.webonn.com/’)])

此时,不是微信回调后,所以code和state都是空的:

paraCode=
paraState=

所以此处需要跳转needRedirect到微信授权

注:

此处,其实有个小难点:

如果给微信授权的回调地址是:

则回调之后,获取用户信息之后,想要跳转回之前的url,就找不到之前的回调地址是多少了

所以此处,把之前的登录成功后回调的地址,传入了,微信授权回调地址中,当作参数:

redirectUri=http://hd.webonn.com/wechat_auth?nextRedirectUrl=http%3A//hd.webonn.com/

而对应的微信授权地址是:

authorizeUrl=https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9xxxxxxxxxxxxxxd&redirect_uri=http%3A//hd.webonn.com/wechat_auth%3FnextRedirectUrl%3Dhttp%253A//hd.webonn.com/&response_type=code&scope=snsapi_userinfo&state=#wechat_redirect

然后就是:

5.进入微信授权的逻辑:

如果用户已经授权了,则自动就回调(不会出现授权页面)

如果用户还没有授权,则跳转到授权页面,用户点击授权,则跳转到回调地址

6.再次进入wechat_auth,此时code不为空

即返回:

http://hd.webonn.com/wechat_auth?nextRedirectUrl=http%3A//hd.webonn.com/

即:

返回:

http://hd.webonn.com/wechat_auth

参数是:

requestArgs=ImmutableMultiDict([(‘state’, u”), (‘code’, u’011uPpnB13QCl00a5poB1FTunB1uPpn9′), (‘nextRedirectUrl’, u’http://hd.webonn.com/’)])

然后此时,发现code不为空,则就不跳转,则进入:

获取到对应的用户信息

解析后,存入数据库

respUserInfoDict = wechat.get_oauth2_userinfo(oauth2Access_token, oauth2Openid)
curUser = saveUserInfoToDb(respUserInfoDict)

输出信息是:

type(respUserInfoDict)=<type ‘dict’>, respUserInfoDict={u’province’: u”, u’openid’: u’oswjmv-QiQp-_5pFB0thKxfCZ8Tc’, u’headimgurl’: u’http://wx.qlogo.cn/mmopen/pER61XSS42q63Aq66EQF8u6ur93JJjShFMHkHWticgdPEOcA9k5nqCQGnXh2WTs4YyRIVc9vbTUHDSQJashJEbGuOI2WgiaaOx/0′, u’language’: u’zh_CN’, u’city’: u”, u’country’: u’\u4e2d\u56fd’, u’sex’: 0, u’privilege’: [], u’nickname’: u’crifan.com’}

然后,去调用,关键的Flask-Login的login_user:

login_user(curUser, remember = True) # 第一个参数传入用户对象,第二个参数 传入 以后是否自动登陆

去记录下来,你已经登录的用户

-》此时,全局的变量current_user,此时就是对应的已登录的用户User类型了

-》就可以去获取你自己的相关的属性了,比如我此处,User有openid,nickname等属性。

curUser = g.user
curUser.openid

-》

执行完login_user,就接着,跳转回到:

需要登录验证的的之前next参数的url中

after wechat auth, redirect to nextRedirectUrl=http://hd.webonn.com/

此处即:

nextRedirectUrl=http://hd.webonn.com/

7.继续访问 / 之前的before_request

此时,User就是我们所希望的User类型了:

g=<flask.g of ‘sipevents’>, g.user=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>, current_user=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>

8.然后真正的,进入到 /

即访问了:

http://hd.webonn.com/

进入到路由 /

此时,把之前在before_request保存到的

g.user拿过来使用

    curUser = g.user
    gLog.debug(“g=%s, curUser=%s”, g, curUser)
    # g=<flask.g of ‘sipevents’>, curUser=<flask_login.AnonymousUserMixin object at 0x7f93ab317390>
    # g=<flask.g of ‘sipevents’>, curUser=<User nickname=u’crifan.com’ openid=oswjmv-QiQp-_5pFB0thKxfCZ8Tc avatar_static_path=img/avatar/oswjmv-QiQp-_5pFB0thKxfCZ8Tc.png>
    gLog.debug(“curUser=%s”, curUser)
    # curUser=<User nickname=u’\u793c\u8c8c’ openid=oswxxxxxxxxxxxxxxxxxxxxxxVVY avatar_static_path=img/avatar/oswxxxxxxxxxxxxxxxxxxxxxxVVY.png>
    # curUser=<flask_login.AnonymousUserMixin object at 0x7f93ab317390>
    gLog.debug(“type(curUser)=%s”, type(curUser))
    # type(curUser)=<class ‘sipevents.models.User’>
    # type(curUser)=<class ‘werkzeug.local.LocalProxy’>
    # type(curUser)=<class ‘werkzeug.local.LocalProxy’>

注意到:

之前没有登录,g.user的值是:flask_login.AnonymousUserMixin的类型

登录后,g.user的值是:我们自己的User类型

不论是否登录,g.user的type都属于:

<class ‘werkzeug.local.LocalProxy’>

类型。

至此,才算完整了实现:

Flask-Login,搭配before_request和login_required,去实现:

访问某些路径/接口/路由 之前,需要登录才可以访问。

且此处,通过跳转到微信授权登录页面,实现微信授权,拿到用户信息,实现登录到过程。

转载请注明:在路上 » [记录]如何在Flask中实现记住微信公众号的用户帐户的登录状态

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
56 queries in 0.120 seconds, using 18.96MB memory