Python Tornado之搭建微信公众号网页授权(六)

       有这么个需求,大学教务处公众号要实现查成绩,一般来说你发送数据行为我们可以拿到客户的openid就是唯一标识,然后如果你绑定了学号,那么我们就会在数据库中找出你的成绩给你返回,这就是查询业务,实现很简单,但是客户慢慢的发现这个交互效果不好,他要看更好看的界面,那么你就得自己写网页了,并且在公众号中调用这个网页。此时就得需要 网页授权。强烈建议 看 官方文档 :如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。个人觉得学到目前为止 有了 openid 了这个就可有可无了吧。但是简单的记录一下,万一以后用的到呢?

接下来又是厚颜无耻的复制官方文档了

关于网页授权的两种scope的区别说明

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

关于网页授权access_token和普通access_token的区别

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;

2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。

关于特殊场景下的静默授权

1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;

2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。

具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

我们要做的事情很简单,就是对于用户的页面访问设置关卡,就是重定向路由。例如小明要从A路口到B城去,B城不重要那么A路口不设防小明直接到B城,如果B城很重要,不是谁都能进的,那么就必须有人在A路口盘问来往路人,并且还得给你护送到B城,因为万一给你放行了 你丫的去C城了怎么办?拦截 护送 就是重定向。

在准备写代码前,到微信公众平台,接口那里配置一下域名

好了 官网讲的很详细 直接上代码 完整代码看这里 这篇博客 

from wxconfig import WxConfig
from urllib import parse
from wxlogger import logger
import requests
import json
""" 用于拦截 对页面的请求 提取用户信息"""
class WxAuthorServer(object):
    """微信网页授权server"""

    """对与请求连接进行重定向,获取用户信息进行网页授权"""
    redirect_uri = '%s/wx/page/wxauthor' % WxConfig.AppHost
    """
    应用授权作用域
    snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid)
    snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
    """
    SCOPE = 'snsapi_base'

    """通过code换取网页授权access_token"""
    get_access_token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?'

    """拉取用户信息"""
    get_userinfo_url = 'https://api.weixin.qq.com/sns/userinfo?'


    def get_code_url(self, state):
        """获取code的url"""
        _dict = {'redirect_uri': self.redirect_uri}
        redirect_uri = parse.urlencode(_dict)
        author_get_code_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&%s&response_type=code&scope=%s&state=%s#wechat_redirect' % (WxConfig.AppID, redirect_uri, self.SCOPE, state)
        return author_get_code_url

    def get_auth_access_token(self, code):
        """通过code换取网页授权access_token"""
        try:
            url = self.get_access_token_url + 'appid=%s&secret=%s&code=%s&grant_type=authorization_code' % (WxConfig.AppID, WxConfig.AppSecret, code)
            r = requests.get(url)
            if r.status_code == 200:
                json_res = json.loads(r.text)
                if 'access_token' in json_res.keys():
                    return json_res
                elif 'errcode' in json_res.keys():
                    errcode = json_res['errcode']
                    logger.error('通过code换取网页授权access_token:'+errcode)
        except Exception as e:
            logger.error('get_auth_access_token:'+str(e))

下面是路由,通过 参数来判断是请求哪个页面 完整代码看这里 这篇博客 

class pageHandler(tornado.web.RequestHandler):
    '''页面跳转控制路由'''
    wx_config = WxConfig()
    '''微信网页授权server'''
    wx_author_server = WxAuthorServer()
    def get(self, flag):
        try:
            if flag == '/wxauthor':
                '''微信网页授权'''
                code = self.get_argument('code')
                state = self.get_argument('state')
                # 获取重定向的url
                redirect_url = self.wx_config.wx_menu_state_map[state]
                if code:
                    # 通过code换取网页授权access_token
                    data = self.wx_author_server.get_auth_access_token(code)
                    openid = data['openid']
                    if openid:
                        # 跳到自己的业务界面
                        self.redirect(redirect_url)
                    else:
                        # 获取不到openid
                        logger.error('获取不到openid')
            # 如果请求的是airkiss页面
            elif flag == '/airkiss':
                self.render('../page/airkiss.html')
            elif flag == '/test':
                self.render('../page/test.html')
        except Exception as e:
            logger.error('pageHandler post'+str(e))

对于请求页面路由来说内部是重定向,page后面就是参数 完整代码看这里 这篇博客 

对于网页授权 目前对于我小白的水准 还未把握,这篇博客先这样,以后再改

看个效果 完整代码看这里 这篇博客 

我又试了一下,我们不进行网页授权而直接访问页面也是可行的,进行网页授权是为了拿到更多的用户信息,如果仅是拿到openid那么你大可不比如此大费周章

html代码在  这篇博客 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖人称王某人的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值