授权流程技术说明

官网授权流程图如下:

java产品许可信息 java 授权码_第三方平台

步骤1:第三方平台方获取预授权码(pre_auth_code)

该API用于获取预授权码。预授权码用于公众号或小程序授权时的第三方平台方安全验证。

接口调用请求说明

http请求方式: POST(请使用https协议)
https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=xxx

POST数据示例:

{
"component_appid":"appid_value" 
}

请求参数说明

参数

说明

component_appid

第三方平台方appid

返回结果示例

{"pre_auth_code":"Cx_Dk6qiBE0Dmx4EmlT3oRfArPvwSQ-oa3NL_fwHM7VI08r52wazoZX2Rhpz1dEw","expires_in":600}

结果参数说明

参数

说明

pre_auth_code

预授权码

expires_in

有效期,为10分钟

 

步骤2:引入用户进入授权页

第三方平台方可以在自己的网站中放置“微信公众号授权”或者“小程序授权”的入口,或生成授权链接放置在移动网页中,引导公众号和小程序管理员进入授权页。

我们这里才用网页扫码授权的方式,注意这个授权地址必须放在我们自己的网页里打开,我们在申请填的域名下打开才行

java产品许可信息 java 授权码_公众号_02

就是上面这个,下面我们会写一个简单的授权页面,动态将获取到的参数放入授权跳转地址中.

 

方式一:授权注册页面扫码授权

授权页网址为:

https://mp.weixin.qq.com/cgi-bin/componentloginpage?component\_appid=xxxx&pre\_auth\_code=xxxxx&redirect\_uri=xxxx&auth\_type=xxx。

参数

是否必填

参数说明

component_appid


第三方平台方appid

pre_auth_code


预授权码

redirect_uri


回调URI

auth_type


要授权的帐号类型, 1则商户扫码后,手机端仅展示公众号、2表示仅展示小程序,3表示公众号和小程序都展示。如果为未制定,则默认小程序和公众号都展示。第三方平台开发者可以使用本字段来控制授权的帐号类型。

biz_appid


指定授权唯一的小程序或公众号

 

获取预授权码以及返回一个授权页面代码:
 

@RestController
public class PreAuthController {

    @Resource
    private WeiXinApi weiXinApi;

    @GetMapping("/testpreauthapi")
    public ModelAndView testPreAuthApi() {

        Map<String, Object> params = new HashMap<>();
        params.put("component_appid", OpenComponentParams.appId);// 前面已经获取到的平台appid

        // 获取预授权码 preAuthCode
        Map<String, Object> preauthcode =
                weiXinApi.preauthcode(OpenComponentParams.ACCESS_TOKEN, params);// 前面已经获取的平台token

        // 授权地址需要的参数信息
        Map<String, Object> result = new HashMap<>();
        result.put("component_appid", OpenComponentParams.appId);
        result.put("pre_auth_code", preauthcode.get("pre_auth_code"));// 预授权码
        result.put("redirect_uri", "https://testwxopenauth.linshang.com/callback");// 回调url
        result.put("auth_type", "2");
        return new ModelAndView("auth", result);// 返回我们自己写的授权页面
    }

}

简单实现的页面代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
	<!-- 我们需要跳转的地址 -->
	<a
		th:href="@{https://mp.weixin.qq.com/cgi-bin/componentloginpage(component_appid=${component_appid},pre_auth_code=${pre_auth_code},redirect_uri=${redirect_uri},auth_type=2)}">发起授权</a>

</body>
</html>

封装的微信api

@FeignClient(name = "weixinapi", url = "https://api.weixin.qq.com")
public interface WeiXinApi {

    /**
     * 获取第三方平台component_access_token.
     * 
     * @param params 发送的参数
     * @return 请求结果
     */
    @PostMapping("/cgi-bin/component/api_component_token")
    Map<String, Object> componentToken(Map<String, Object> params);

    /**
     * 获取预授权码pre_auth_code.
     * 
     * @param componentAccessToken 请求token
     * @param params 第三方平台方appid
     * @return 预授权码pre_auth_code
     */
    @PostMapping(value = "/cgi-bin/component/api_create_preauthcode")
    Map<String, Object> preauthcode(
            @RequestParam("component_access_token") String componentAccessToken,
            Map<String, Object> params);

    /**
     * 使用授权码换取公众号或小程序的接口调用凭据和授权信息.
     * 
     * @param componentAccessToken 平台可访问授权码
     * @param params post的参数
     * @return api执行结果
     */
    @PostMapping("/cgi-bin/component/api_query_auth")
    Map<String, Object> apiQueryAuth(
            @RequestParam("component_access_token") String componentAccessToken,
            Map<String, Object> params);

}

静态类:

public class OpenComponentParams {

  public static String aesKey = "0JpPmBUBCe7EFeEg9EDcEklWYGXFNLg6nGMqKV2gDyT"; //aeskey
  public static String COMPONENT_TOKEN = "linshang-open-mini"; //平台设定的token
  public static String appId = "wx59bfe3a873b9d9f4";//平台appid
  public static String secret = "1de8bc72c6c21e8ad3f32218195399b6";//平台秘钥
  public static String pre_auth_code="";//预授权码
  public static String TICKET = "";// 第三方ticket
  public static String ACCESS_TOKEN = "";// 平台token

}

步骤3:使用授权码换取公众号或小程序的接口调用凭据和授权信息

在上一步点击完成扫码授权之后,我们在授权时留的回调地址会接收到微信发来的一个临时auth_code,有效时间比较短,所以在收到回调时,我们马上就用它去获换取authorizer_access_token和authorizer_refresh_token。 

接口调用请求说明

http请求方式: POST(请使用https协议)
https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=xxxx

POST数据示例:

{
"component_appid":"appid_value" ,
"authorization_code": "auth_code_value"
}

请求参数说明

参数

说明

component_appid

第三方平台appid

authorization_code

授权code,会在授权成功时返回给第三方平台,详见第三方平台授权流程说明

返回结果示例

{
"authorization_info": {
"authorizer_appid": "wxf8b4f85f3a794e77",
"authorizer_access_token": "QXjUqNqfYVH0yBE1iI_7vuN_9gQbpjfK7hYwJ3P7xOa88a89-Aga5x1NMYJyB8G2yKt1KCl0nPC3W9GJzw0Zzq_dBxc8pxIGUNi_bFes0qM",
"expires_in": 7200,
"authorizer_refresh_token": "dTo-YCXPL4llX-u1W1pPpnp8Hgm4wpJtlR6iV0doKdY",
"func_info": [
{
"funcscope_category": {
"id": 1
}
},
{
"funcscope_category": {
"id": 2
}
},
{
"funcscope_category": {
"id": 3
}
}
]
}}

结果参数说明

参数

说明

authorization_info

授权信息

authorizer_appid

授权方appid

authorizer_access_token

授权方接口调用凭据(在授权的公众号或小程序具备API权限时,才有此返回值),也简称为令牌

expires_in

有效期(在授权的公众号或小程序具备API权限时,才有此返回值)

authorizer_refresh_token

接口调用凭据刷新令牌(在授权的公众号具备API权限时,才有此返回值),刷新令牌主要用于第三方平台获取和刷新已授权用户的access_token,只会在授权时刻提供,请妥善保存。 一旦丢失,只能让用户重新授权,才能再次拿到新的刷新令牌

func_info

授权给开发者的权限集列表,ID为1到26分别代表: 1、消息管理权限 2、用户管理权限 3、帐号服务权限 4、网页服务权限 5、微信小店权限 6、微信多客服权限 7、群发与通知权限 8、微信卡券权限 9、微信扫一扫权限 10、微信连WIFI权限 11、素材管理权限 12、微信摇周边权限 13、微信门店权限 15、自定义菜单权限 16、获取认证状态及信息 17、帐号管理权限(小程序) 18、开发管理与数据分析权限(小程序) 19、客服消息管理权限(小程序) 20、微信登录权限(小程序) 21、数据分析权限(小程序) 22、城市服务接口权限 23、广告管理权限 24、开放平台帐号管理权限 25、 开放平台帐号管理权限(小程序) 26、微信电子发票权限 41、搜索widget的权限 请注意: 1)该字段的返回不会考虑公众号是否具备该权限集的权限(因为可能部分具备),请根据公众号的帐号类型和认证情况,来判断公众号的接口权限。

代码:

@RestController
public class CallbackController {
    private Log log = LogFactory.getLog(this.getClass());
    @Resource
    private WeiXinApi weiXinApi;

    @RequestMapping("/callback")
    public String callback() {
        Map<String, String[]> parameterMap = WebUtils.getRequest().getParameterMap();
        if (parameterMap.containsKey("auth_code") && parameterMap.containsKey("expires_in")) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("authorization_code", StringUtils.join(parameterMap.get("auth_code"), ","));
            params.put("component_appid", OpenComponentParams.appId);
            
            //获取小程序的凭据和授权信息
            Map<String, Object> result =
                    weiXinApi.apiQueryAuth(OpenComponentParams.ACCESS_TOKEN, params);
            
            //保存调用凭据和授权信息
            log.info(result);
        }

        return "info";
    }

}

这里拿到了authorizer_access_token之后就可以代小程序进行业务接口的调用开发了,注意这个token有效时间为两个小时,所以要及时刷新,authorizer_refresh_token也要保存好。

 

最后:用户授权时是通过我们授权地址填的回调通知我们的,有时候用户会取消和更新授权,取消和更新的授权通知和发送ticket那个接口是一样的,所以我们在开始拿ticket的接口要做好消息事件的类型接收,针对不同的通知做不同的处理。

当公众号对第三方平台进行授权、取消授权、更新授权后,微信服务器会向第三方平台方的授权事件接收URL(创建第三方平台时填写)推送相关通知。

POST数据示例(授权成功通知)

<xml>
<AppId>第三方平台appid</AppId>
<CreateTime>1413192760</CreateTime>
<InfoType>authorized</InfoType>
<AuthorizerAppid>公众号appid</AuthorizerAppid>
<AuthorizationCode>授权码(code)</AuthorizationCode>
<AuthorizationCodeExpiredTime>过期时间</AuthorizationCodeExpiredTime>
<PreAuthCode>预授权码</PreAuthCode>

<xml>

POST数据示例(取消授权通知)

<xml>
<AppId>第三方平台appid</AppId>
<CreateTime>1413192760</CreateTime>
<InfoType>unauthorized</InfoType>
<AuthorizerAppid>公众号appid</AuthorizerAppid>

</xml>

POST数据示例(授权更新通知)

<xml>
<AppId>第三方平台appid</AppId>
<CreateTime>1413192760</CreateTime>
<InfoType>updateauthorized</InfoType>
<AuthorizerAppid>公众号appid</AuthorizerAppid>
<AuthorizationCode>授权码(code)</AuthorizationCode>
<AuthorizationCodeExpiredTime>过期时间</AuthorizationCodeExpiredTime>
<PreAuthCode>预授权码</PreAuthCode>
<xml>

字段说明:

字段名称

字段描述

AppId

第三方平台appid

CreateTime

时间戳

InfoType

unauthorized是取消授权,updateauthorized是更新授权,authorized是授权成功通知

AuthorizerAppid

公众号或小程序

AuthorizationCode

授权码,可用于换取公众号的接口调用凭据,详细见上面的说明

AuthorizationCodeExpiredTime

授权码过期时间

PreAuthCode

预授权码