2019-12-13 10:39:03 tianxiaojie_blog 阅读数 8

介绍

网页授权分两种 snsapi_basesnsapi_userinfo
snsapi_base 需要关注公众号才可以获取用户信息,但是用户无感
snsapi_userinfo 则不需要关注公众号,但需要用户确认是否被获取
这里以 snsapi_userinfo 为例实现获取用户信息

建立一个访问页面index.php

<?php
//scope=snsapi_userinfo实例
$appid='微信appid';
$redirect_uri = urlencode ( 'http://存放地址/getUserInfo.php' );
$url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
header("Location:".$url);

建立getUserInfo.php

<?php

$appid = "微信appid";
$secret = "微信secret";
$code = $_GET["code"];

//第一步:取得openid
$oauth2Url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$secret&code=$code&grant_type=authorization_code";
$oauth2 = getJson($oauth2Url);

//第二步:根据全局access_token和openid查询用户信息
$access_token = $oauth2["access_token"];
$openid = $oauth2['openid'];
$get_user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN";
$userinfo = getJson($get_user_info_url);

//打印用户信息
print_r($userinfo);

function getJson($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return json_decode($output, true);
}

访问

将两个文件直接放于服务器上,访问 index.php 地址即可

错误

access_token 非法 错误

解决方案参考

40001 无权限 错误

细察上面代码引用的
接口地址是
https://api.weixin.qq.com/sns/userinfo
而不是
https://api.weixin.qq.com/cgi-bin/user/info

获取用户信息思路

  1. 打开index.php页面跳转到getUserInfo.php页面
  2. 获取并存储用户信息,跳转到内容页面
    这么做是因为 网页授权获取用户信息 调用次数500 0000 次
    在这里插入图片描述

存储用户信息的思路

每次都进行建立连接,这样的实现方式是短链接,用完即关闭连接。因为mysql支持同一时间几千个连接数。而且我们的连接也没有到达一定量,不需要缓存实例或建立长连接

微信信息表结构

wx_OpenAndShare  
id,openid,nickname,phone,open,share,project,time
wx_Information
id,openid,nickname,sex,province,city,country,headimgurl,language,phone,privilege,unionid,project,time

在这里插入图片描述

2016-10-27 16:45:22 xiaoyezihanghui 阅读数 5061


释: 我是订阅号,申请的微信开发测试账号,操作授权登录


1.  下载web开发工具


2.  在公众号列表中, 开发者工具-》web开发工具-> 绑定开发者账号 -》输入你的微信号(微信号需关注公众号才可绑定),邀请绑定在微信客户端确认邀请即可


3.  在测试管理账号中, 网页授权获取用户基本信息  接口,点击修改  填充(授权回调页面域名),沙盒测试环境不限ip和域名,我填充的ip ( 注释: ip填充只需 如192.168.0.1:port,前缀不需要http,此坑已踩)


4.  授权链接 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx58caa75dbeb054aa&redirect_uri=http://192.168.0.1:8014/wechat_login&response_type=code&scope=snsapi_userinfo&state=1   回调按照自己的需求更改即可

2017-07-26 11:23:55 sxdtzhaoxinguo 阅读数 22662

摘要:上一篇总结了微信企业号开发的入门篇,access_token接口调用,这篇咱们来看下微信企业号开发中的网页授权接口调用,这个接口一般都是用来实现微信企业号应用免登录或者获取关注的微信用户的个人信息时会用到。

 

下面摘自微信企业号官方文档:

 

网页授权

概述

 

企业微信提供了OAuth的授权登录方式,可以让网页和企业微信共享用户ID,从而免去登录的环节。

此文档面向网页开发者介绍企业微信网页授权如何使用及相关注意事项。

关于网页授权的可信域名

1、在开始使用网页授权之前,开发者需要先登录到企业管理端后台,选择“企业应用”选项卡,进入需要使用网页授权的应用并编辑“可信域名”表单项,此选项将用于网页OAuth2.0授权的时候进行安全验证。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头

2、可信域名配置规范为全域名,且需要通过ICP备案(否则在微信侧jssdk功能失效)。比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权

3、域名的验证逻辑说明:由于一个企业可以自定义多个应用,每个应用都可以配置一个安全域名,在做oauth跳转的时候,只需要携带coprid即可,企业微信的后台会遍历该企业下面配置的所有应用并检查其配置的可信域名,只要任意一个应用的可信域名匹配则校验成功。

关于UserID机制

UserId用于在一个企业内唯一标识一个用户,通过网页授权接口可以获取到当前用户的UserId信息,如果需要获取用户的更多信息可以调用通讯录管理的成员接口来获取。

接入流程说明

企业应用中的URL链接(包括自定义菜单或者消息中的链接),均可通过OAuth2.0验证接口来获取成员的UserId身份信息。注意:此URL的域名,必须完全匹配企业应用设置项中的“可信域名”(如果你的redirect_uri有端口号,那么“可信域名”也必须加上端口号),否则跳转时会提示redirect_uri参数错误。

通过此接口获取成员身份会有一定的时间开销。对于频繁获取成员身份的场景,建议采用如下方案:
1、企业应用中的URL链接直接填写企业自己的页面地址
2、成员操作跳转到步骤1的企业页面时,企业后台校验是否有标识成员身份的cookie信息,此cookie由企业生成
3、如果没有匹配的cookie,则重定向到OAuth验证链接,获取成员的身份信息后,由企业后台植入标识成员身份的cookie信息
4、根据cookie获取成员身份后,再进入相应的页面

 

 

关键步骤

获取code

 

如果企业需要在打开的网页里面携带用户的身份信息,第一步需要构造如下的链接来获取code参数:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&agentid=AGENTID&state=STATE#wechat_redirect

参数说明:

参数 必须 说明
appid 企业的CorpID
redirect_uri 授权后重定向的回调链接地址,请使用urlencode对链接进行处理
response_type 返回类型,此时固定为:code
scope 应用授权作用域。
snsapi_base:静默授权,可获取成员的基础信息;
snsapi_userinfo:静默授权,可获取成员的详细信息,但不包含手机、邮箱;
snsapi_privateinfo:手动授权,可获取成员的详细信息,包含手机、邮箱。
 
agentid 企业应用的id。
当scope是snsapi_userinfo或snsapi_privateinfo时,该参数必填。
注意redirect_uri的域名必须与该应用的可信域名一致。
 
state 重定向后会带上state参数,企业可以填写a-zA-Z0-9的参数值,长度不可超过128个字节
#wechat_redirect 终端使用此参数判断是否需要带上身份信息

员工点击后,页面将跳转至 redirect_uri?code=CODE&state=STATE,企业可根据code参数获得员工的userid。code长度最大为512字节。

 

 

 

权限说明:
企业无限制;第三方使用snsapi_privateinfo的scope时,应用必须有’成员敏感信息授权’的权限。

根据code获取成员信息

请求方式:GET(HTTPS
请求地址:https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE

参数说明:

参数 必须 说明
access_token 调用接口凭证
code 通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

权限说明:
跳转的域名须完全匹配access_token对应应用的可信域名。

返回结果:
a) 当用户为企业成员时返回示例如下:

  1. {
  2. "errcode":0,
  3. "errmsg":"ok",
  4. "UserId":"USERID",
  5. "DeviceId":"DEVICEID",
  6. "user_ticket":"USER_TICKET"
  7. "expires_in":7200
  8. }

 

参数 说明
errcode 返回码
errmsg 对返回码的文本描述内容
UserId 成员UserID
DeviceId 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响)
user_ticket 成员票据,最大为512字节。
scope为snsapi_userinfo或snsapi_privateinfo,且用户在应用可见范围之内时返回此参数。
后续利用该参数可以获取用户信息或敏感信息。
 
expires_in user_token的有效时间(秒),随user_ticket一起返回

非企业成员授权时返回示例如下:

 

 

 

 

  1. {
  2. "errcode":0,
  3. "errmsg":"ok",
  4. "OpenId":"OPENID",
  5. "DeviceId":"DEVICEID"
  6. }

 

 

 

 

参数 说明
errcode 返回码
errmsg 对返回码的文本描述内容
OpenId 非企业成员的标识,对当前企业唯一
DeviceId 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响)

出错返回示例:

 

  1. {
  2. "errcode":40029,
  3. "errmsg":"invalid code"
  4. }

 

 

 

下面来看具体的代码实现:

 

1.SimpleOAuth2Controller.java

 

package com.eqiao.bidata.weixin.controller;

import com.eqiao.bidata.weixin.common.AccessToken;
import com.eqiao.bidata.weixin.common.Result;
import com.eqiao.bidata.weixin.common.WeiXinQiYeConstants;
import com.eqiao.bidata.weixin.common.WeiXinQiYeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;

/**
 * 单纯实现OAuth2验证,不使用注解及拦截器
 * Created by zhaoxinguo on 2017/7/11.
 */
@Controller
public class SimpleOAuth2Controller {

    private Logger logger = LoggerFactory.getLogger(SimpleOAuth2Controller.class);

    /**
     * 拼接网页授权链接
     * 此处步骤也可以用页面链接代替
     * @return
     */
    @RequestMapping(value = { "/oauth2wx.do" })
    public String Oauth2API(HttpServletRequest request){
        //获取项目域名
        String requestUrl = request.getServerName();
        String contextPath = request.getContextPath();
        logger.info("domain name: " + requestUrl + " project name: " + contextPath);
        //拼接微信回调地址
        String backUrl ="http://" + requestUrl + contextPath + "/oauth2me.do";
        String redirect_uri = "";
        try {
            redirect_uri = java.net.URLEncoder.encode(backUrl, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            logger.error("ecdoe error: " + e.getMessage());
        }
        String oauth2Url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + WeiXinQiYeConstants.CORPID + "&redirect_uri=" + redirect_uri
                + "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
        return "redirect:" + oauth2Url;
    }

    /**
     * 授权回调请求处理
     * @return
     */
    @RequestMapping(value = { "/oauth2me.do" })
    public String oAuth2Url(HttpServletRequest request, @RequestParam String code){
        // 调用获取access_token的接口
        AccessToken accessToken = WeiXinQiYeUtil.access_token();
        HttpSession session = request.getSession();
        if (accessToken != null && accessToken.getAccess_token() != null) {
            // 调用获取用户信息的接口
            String UserId = getMemberGuidByCode(accessToken.getAccess_token(), code, WeiXinQiYeConstants.AGENTID);
            logger.info("UserId: " + UserId);
            if (UserId != null) {
                session.setAttribute("UserId", UserId);
                logger.info("UserId放入session成功!");
            }
        }
        // 这里简单处理,存储到session中
        return "user/result";
    }

    /**
     * 调用接口获取用户信息
     *
     * @param token
     * @param code
     * @return
     */
    public String getMemberGuidByCode(String token, String code, String agentId) {
        logger.info("code==" + code + " token=" + token + " agentId=" +agentId);
        Result result = WeiXinQiYeUtil.oAuth2GetUserByCode(token, code, agentId);
        logger.info("result= " + result);
        if (result.getErrcode().equals("0")) {
            if (result.getUserId() != null  && result.getUserId().length() > 0) {
                // 此处可以通过微信授权用code还钱的Userid查询自己本地服务器中的数据
                logger.info("result.getUserId(): " + result.getUserId());
                return result.getUserId();
            }
        }
        return "";
    }

}

 

 

2.OAuth2验证接口根据code获取成员信息接口调用方法:

 

/**
     * OAuth2验证接口根据code获取成员信息
     *
     * @param token
     * @param code
     * @return
     */
    public static Result oAuth2GetUserByCode(String token, String code, String agentId) {
        Result result = new Result();
        String menuUrl = WeiXinQiYeConstants.GET_OAUTH2_URL.replace("ACCESS_TOKEN", token).replace("CODE", code).replace("AGENTID", agentId + "");
        String userinfo = JHttpUtils.doGet(menuUrl);
        logger.info("userinfo: " + userinfo);
        JSONObject jsonObject = null;
        if (userinfo != null) {
            try {
                jsonObject = JSONObject.fromObject(userinfo);
                logger.info("jsonObject: " + jsonObject);
                if (jsonObject.getString("UserId") != null && jsonObject.getString("UserId").length() > 0) {
                    result.setErrmsg(jsonObject.getString("errmsg"));
                    result.setErrcode(jsonObject.getString("errcode"));
                    result.setUserId(jsonObject.getString("UserId"));
                } else {
                    result.setErrmsg(jsonObject.getString("errmsg"));
                    result.setErrcode(jsonObject.getString("errcode"));
                }
            } catch (Exception e) {
                result.setErrmsg("accessToken 超时......");
                result.setErrcode("42001");
            }
        }
        return result;
    }

 

以上就是网页授权接口的调用示例,最后调用成功后,会打印出微信企业号的UserId(前提是这个微信号必须先关注改企业号才行)。

 

 

3.访问方法测试网页授权接口:http://域名:端口号/项目名称/oauth2wx.do

 

4.源码下载地址:http://git.oschina.net/micai/weixin-qiye

 

5.如有问题请扫描下面的微笑二扫码联系,楼主会尽力帮大家解决遇到的问题!

标题

 

 

2016-10-09 11:45:56 iamlyky 阅读数 477

微信开发 - 获取网页授权access_token、openid以及用户信息

 

 

微信公众平台开发中,会遇到一个叫openid的东西,它是公众号普通用户的一个唯一标识,即同一用户针对同一公众号的openid是唯一的。

 

在关注者与公众号产生消息交互后,公众号可获得关注者的openid,但请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的openid。

 

 

获取网页授权access_token、openid

 

一、用户同意授权,获取code

 

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

 

1、appid 公众号的唯一标识

2、redirect_uri 授权后重定向的回调链接地址,请使用urlencode对链接进行处理

3、response_type 返回类型,请填写code

4、scope 应用授权作用域

  (1)snsapi_base:不弹出授权页面,直接跳转,只能获取用户openid

  (2)snsapi_userinfo:弹出授权页面,可通过openid拿到昵称、性别、所在地。

5、state 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节

6、#wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数

 

注意这个接口中有个参数scope 默认有2个值snsapi_base和snsapi_userinfo,这个接口会根据scope 来生成不同的code并且获取不同作用的access_token,不管scope传什么值都能在得到对应access_token的同时得到openid, 如果你只需要得到opendid 那使用snsapi_base参数到此结束了,如果需要获取用户的其他信息比如昵称、地址、就要用snsapi_userinfo 会弹出授权。

snsapi_base为例:以下链接可设置为微信公众平台"自定义菜单"的页面地址,点击后会发送请求到redirect_uri,并携带参数code。

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe49d******43c1cd&redirect_uri=http%3A%2F%2FdomainName%2FserverName%2FcontrollerName%2FactionName

&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect

 

二、通过code换取网页授权access_token及openid

 

def getOpenId(String code)
{
    def CODE = code
    def APPID = "wxe49d******43c1cd"
    def SECRET = "217c05ff85************db8f4c9371"

    URL url = new URL("https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code")
    def params = "APPID=" + URLEncoder.encode(APPID, "UTF-8") + 
                 "&SECRET=" + URLEncoder.encode(SECRET, "UTF-8") + 
                 "&CODE=" + URLEncoder.encode(CODE, "UTF-8")

    HttpURLConnection connection = (HttpURLConnection) url.openConnection()
    connection.setDoOutput(true)
    connection.setRequestMethod("POST")
    connection.outputStream.withWriter { Writer writer -> writer.write params }
    def response = connection.inputStream.withReader { Reader reader -> reader.text }
    def openId = JSON.parse(response).getAt("openid")
    return openId
}

正确时返回的JSON数据包如下:
{
   "access_token":"ACCESS_TOKEN",
   "expires_in":7200,
   "refresh_token":"REFRESH_TOKEN",
   "openid":"OPENID",
   "scope":"SCOPE"
}

 注意:其中,APPID、SECRET可在微信公众平台中获取。 

 

获取用户信息

 

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

这个接口中的access_token是获取code的时候scope 参数为snsapi_userinfo时换取的网页授权access_token

微信还有一个获取用户基本信息的接口,但是这个接口需要你关注了公众号。 

https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

 




此接口的access_token 是接口基础调用access_token 而不是网页授权access_token。在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

 

批量获取用户信息

 

开发者可通过该接口来批量获取用户基本信息。最多支持一次拉取100条。

 

https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=ACCESS_TOKEN





 此接口的access_token 同样也是接口基础调用的access_token。

2018-04-19 16:54:03 ws932734384 阅读数 24737

        本人最近要做微信公众号网页开发的项目,其中有个需求是判断用户是否关注公众号,由于之前没有接触过微信授权的东西,所以提前开始做调研。在度娘上看了好多博客、百度知道、百度经验、知乎问答等,还仔细阅读了微信公众平台开发文档,大致了解到:

        微信网页授权分两种,第一种是snsapi_base(静默授权,用户无感知),第二种是snsapi_userinfo(第一次授权需要用户点击登录确认)。静默授权只需要两步就能拿到开发者需要的openID,而第二种授权方式,一共需要四步,可以拉取到用户信息(昵称、头像等)。具体过程这里不在赘述,参阅微信开发者文档。


        但是,本人发现一个不好的事情,获取到的用户信息里,并没有度娘告诉我的用于判断用户是否关注公众号的字段 subscribe 。然后,继续查阅博客、百度知道、百度经验、知乎问答,其中,有一篇博客让我如获至宝,下面是博客的截图:


        然后我就天真的相信,只有在unionID机制下,获取到的用户信息里才会有 subscribe 字段。后来,查看微信公众平台开发文档,其中有一段:


        那么,只有把公众号绑定到微信开放平台上才能使用unionID机制。所以自己就注册了一个微信开放平台,要绑定公众号的时候发现,只有完成开发者资质认证才能绑定。但是认证需要:



        以上只是一部分。这哪儿是我一个开发能做的事儿啊,所以向项目经理说明了情况,又向技术中心老大申请……,经过了一系列繁杂又不太顺利的流程。最后,让我来注册,需要什么材料找行政要。

        当然,在协调的过程中,我也没闲着,咨询了做过微信网页授权的同事,自己也继续翻阅微信开发文档(相当烂)、在本地尝试授权,获取用户信息,最终发现:不需要unionID机制,也能获取用户基本信息,拿到 subscribe 字段。那么正题来了!


微信网页授权并获取用户基本信息(是否关注公众号、头像、昵称等)步骤:  

          1、用户同意授权,获取code(使用静默授权即可)

               参阅 微信网页授权 第一步

            2、通过code换取  网页授权access_token  和 openID(此处的access_token为网页授权过程专用)

                参阅 微信网页授权 第二步

            3、使用AppId和AppSecret:获取access_token

                参阅  获取access_token

            4、使用openID和access_token获取用户基本信息

                参阅 获取用户基本信息(包括UnionID机制)

最终获取到的用户基本信息如下图:

        


        好了,到这里终于拿到了我需要的判断用户是否关注公众号的字段: subscribe 。


        饶了这么大圈子,有些感触:微信公众平台开发文档不容易看懂,unionID机制到底是啥,绑定了开放平台才叫unionID机制吗,那我现在这种调接口的方法(并没有绑定微信开放平台)属于unionID机制吗。

        再多说一句,其实这些逻辑,绝大部分是在后端完成的(access_token、appsecret安全等级都比较高)。所以,作为前端,只要调接口==》回调地址,再调接口==》得到用户基本信息。

微信授权登录

阅读数 851

没有更多推荐了,返回首页