微信登陆

1.首先页面点击微信图标

2.后台方法调用微信,用户授权:

  • 前台向后台请求方法:
@wechat.route('/open_weixin', methods=['GET'])
def open_weixin():
    """第一步:用户同意授权,获取code
    redirect_uri :用户授权之后回调地址
    state:回调会带着此参数
    """
    return_url = request.args.get("return_url", "")
    url = _get_open_weixin_url("snsapi_userinfo", return_url)
    return redirect(url)

def _get_open_weixin_url(scope, return_url=None, ordernum=None, ip=None):
    """获取微信授权页面url
    scope参数:
    snsapi_base 静默授权不需要用户操作,
    snsapi_userinfo 需要用户授权然后获取用户基本信息
    state :重定向后会带上state参数,如果你回调需要参数就放到这里,最多128字节
    redirect_uri:为微信回调地址
    appid: "qwb*********56d"  公众号的唯一标识
    """
    # 网页授权两种方式 回调不一样,1 静默授权只获取openid 2 用户授权获取用户信息,
    redirect_uri = ""
    state = ""
    if scope and scope == "snsapi_userinfo":
        redirect_uri = urllib.quote(
            os.path.join("http://", DOMAIN_NAME, "wechat/wechat_user_info")
        )
        if return_url:
            state = return_url
    else:
        redirect_uri = urllib.quote(
            os.path.join("http://", DOMAIN_NAME, "wechat/snsapi_base_open_id"))
        state = "%s_%s" % (ordernum, ip)
    url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={appid}\
&redirect_uri={redirect_uri}&response_type=code&scope={scope}\
&state={state}#wechat_redirect".format(
        appid=appid, redirect_uri=redirect_uri,
        state=state, scope=scope)
    return url

最后return redirect(url)重定向去请求威信接口。
尤其注意:跳转回调redirect_uri,应当使用https链接来确保授权code的安全性。

3.微信回调:

  • snsapi_base 授权只获取用户openid回调:
    openid:用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
    这个是微信给微信每个用户分配的一个唯一标识,这里微信登录需要获取用户的基本信息,这里回调没啥用,如果别的操作需要获取用户的openid 可以这样获取
    @wechat.route('/snsapi_base_open_id', methods=['GET'])
    def snsapi_base_open_id():
    """静默授权回调方法
    获取openid回调地址"""
    print '==============>>>>>>>>>snsapi_base_open_id'
    print request.args.items().str()
    print
    code = request.args.get("code")
    state = request.args.get("state").split("_")
    ordernum = state[0]
    ip = state[1]

      # 通过code换取网页授权access_token
      view = _get_web_access_token(code)
      openid = view['openid']
      webutil.session_set_user_open_id(ordernum, openid)
      return redirect(url_for("order.pay", ordernum=ordernum, ip=ip))
      # return render_template("order/pay.html", view=view, ordernum=ordernum,
      # ip=ip)
    
  • snsapi_userinfo 获取用户基本信息回调:

@wechat.route('/wechat_user_info', methods=['GET', 'POST'])
def wechat_user_info():
    '''
    用户授权回调方法
    微信获取用户基本信息
    1 第一步:用户同意授权,获取code

    2 第二步:通过code换取网页授权access_token

    3 第三步:刷新access_token(如果需要)

    4 第四步:拉取用户信息(需scope为 snsapi_userinfo)

    5 附:检验授权凭证(access_token)是否有效
    '''
    # 第一步:用户同意授权,获取code

    code = request.args.get("code")
    return_url = request.args.get("state")
    # 用户拒绝授权不会返回code参数
    if not code:
        return redirect(url_for('user.login'))
    # 通过code换取网页授权access_token
    view = _get_web_access_token(code)
    # 失败返回
    if not view or not view.get("openid"):
        return redirect(url_for('user.login'))
    access_token = view['access_token']
    openid = view['openid']

    # 判断此openid是否注册过
    user = User.query.filter_by(wx_open_id=openid).first()
    if user:
        return _wechat_login(user, return_url)

    # 检验授权凭证(access_token)是否有效
    val = _validation_access_token(access_token, openid)
    if val != "ok":
        # 刷新access_token
        new_view = _refresh_access_token(view['refresh_token'])
        access_token = new_view['access_token'] if new_view else ""
        openid = new_view['openid'] if new_view else ""
    user_view = _get_wechat_user_info(access_token, openid)
    # 失败返回
    if not user_view:
        return redirect(url_for('user.login'))

    # 为用户注册账号
    user = _wechat_register_user(user_view)
    return _wechat_login(user, return_url)

下面是获取网页授权的access_token:

def _get_web_access_token(code):
    """获取网页授权access_token 这个用来获取用户信息用
    access_token:网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
    expires_in:access_token接口调用凭证超时时间,单位(秒)
    refresh_token:用户刷新access_token
    openid:用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
    scope:用户授权的作用域,使用逗号(,)分隔
    """
    params = urllib.urlencode(
        {
            'appid': appid, 'secret': secret, 'code': code,
            'grant_type': 'authorization_code'
        }
    )
    f = urllib.urlopen(
        "https://api.weixin.qq.com/sns/oauth2/access_token?%s" % params)
    res = json.loads(f.read())
    view = {}
    if res and res.get("openid"):
        view = {"access_token": res.get("access_token"),
                "expires_in": res.get("expires_in"),
                "refresh_token": res.get("refresh_token"),
                "openid": res.get("openid"),
                "scope": res.get("scope")}
    return view

这里获取用户基本信息:

def _get_wechat_user_info(access_token, openid):
    '''微信获取用户基本信息
     access_token 网页授权的access_token
     openid:普通用户标识,对当前公众号唯一
     lang:国家地区语言版本,可不填 zh_CN 简体 zh_TW 繁体 en 英文
     返回参数:
    "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", #用户的标识,对当前公众号唯一
    "nickname": "Band",#用户的昵称
    "sex": 1,#用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
    "city": "广州",
    "province": "广东",
    "country": "中国",
    "headimgurl":"" ,#用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
    "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL", #只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。
    "privilege":用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
    '''
    params = urllib.urlencode(
        {'access_token': access_token, 'openid': openid, 'lang': 'zh_CN'})
    f = urllib.urlopen("https://api.weixin.qq.com/sns/userinfo?%s" % params)
    res = json.loads(f.read())
    view = {}
    if res and res.get("openid"):
        view = {
            "openid": res.get("openid"),
            "nickname": res.get("nickname"),
            "sex": res.get("sex"),
            "city": res.get("city"),
            "province": res.get("province"),
            "country": res.get("country"),
            "headimgurl": res.get("headimgurl")
        }
    return view

然后给微信用户注册一个帐号,登录上就可以了;
其实就是用户授权微信获取用户信息,给用户注册帐号登录上;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容