微信开放平台_微信开放平台测试账号 - CSDN
精华内容
参与话题
  • 微信开放平台和公众平台的区别 开放平台是网站或app使用的接口平台,利用开放平台可在自己的网站或app上开发微信帐户登录、微信分享等功能! 公众平台是微信号的一种,也具有开发功能,是在公众号中开发出更多功能...

    微信开放平台和公众平台的区别

    开放平台是网站或app使用的接口平台,利用开放平台可在自己的网站或app上开发微信帐户登录、微信分享等功能!
    公众平台是微信号的一种,也具有开发功能,是在公众号中开发出更多功能,例如微网站等!
    简单来讲,公众平台的开发功能是在微信平台的基础上的,而开放平台是在你自己的平台上开发的与微信相关的一些功能

     

    进行第三方开发之前最好拥有 微信公众平台 的开发经验,因为说实话,这次的文档比之微信公众平台开发者文档差了不止一个档次,没有相关的开发经验,很难看懂。

    注册第三方平台
    老一套,需要一堆认证手续以及300块。 

    注åæå页é¢
    如图,新建一个公众号第三方平台,然后通过审核即可。

    其中注意一下,前期测试的时候,授权测试公众号列表,网页开发域名,白名单IP地址列表这三项一定要核对无误,每次修改都会重新审核(不过很快就会通过)。因为填错所出现的报错信息文档里面是没有任何说明,甚至是有的错误码文档里也没有。另一篇文章里记录了我第一天开发时遇见的问题,可以参考一下http://blog.csdn.net/goodzyw/article/details/45191143

    开发文档
    官方的开发文档在资源中心里,但是里面具体的东西我每次都要找好久……这里我稍微整理一下吧

    设计资源
    指的是一些按钮,图表等等,官方直接进行了统一,你可以拿来直接使用。

    权限集
    你所能使用的功能取决于给你授权的那个公众号所拥有的权限以及它给你授权的权限,具体规则可以参考这个权限集。

    公众号授权给开放平台流程
    总体说明->三、公众号一键登录授权给第三方平台方的技术流程 
    (是的你没有看错,这么重要且复杂的流程直接写在总体说明里,然后后面的目录就没有其他说明了) 
    这需要注意的是,所有的操作必须在之前所填写的网页开发域名下,否则会报错。

    接下来我会按照 公众号进入页面->公众号授权->获取公众号账户信息这个流程进行一下说明

    公众号进入页面
    具体效果可以参考微盟这种做公众号开发的平台。简单说就是进入你准备的官网,上面有一个按钮,引导用户进入一个第三方页面:https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=xxxx&pre_auth_code=xxxxx&redirect_uri=xxxx,xxx换成你自己的参数 

    ææ页é¢

    ,这是用户同意授权后,会弹出安全认证,就是公众号的安全管理者需要扫码认证,成功后进入下一步公众号授权的后台流程

    公众号授权
    这里涉及到的全部信息均在 代公众号实现业务->代公众号调用接口 里面

    component_verify_ticket
    component_verify_ticket由公众平台每隔10分钟,持续推送给第三方平台方(在创建公众号第三方平台审核通过后,才会开始推送),推送地址为授权事件接收URL(取消授权也调用此地址)

    component_access_token
    第三方的access_token获取需要”component_appid” ,”component_appsecret”, “component_verify_ticket” ,与公众平台一样,后续需要调用接口的地方几乎都要带着它

    pre_auth_code
    预授权码,作用就是引导用户进入第三方授权页面的参数之一,也就是说那个链接不是静态的,每次都要动态生成

    authorization_code
    授权成功后,会在回调地址,也就是redirect_uri中为你添加一个auth_code(是的这里是auth_code,然后回头让你上传的名字就要改成authorization_code)

    authorizer_access_token,authorizer_refresh_token
    使用授权码换取公众号的授权信息,调用此接口后获取的两个参数,其中 
    authorizer_refresh_token(在授权的公众号具备API权限时,才有此返回值),只会在授权时刻提供,请妥善保存。 一旦丢失,只能让用户重新授权,才能再次拿到新的刷新令牌 
    至此授权流程完成,进入获取公众号常规信息流程

    获取授权方的账户信息
    通过上述流程,应该就能拿到authorizer_appid,再配合component_appid,就可以拿到账户信息,比如头像什么的。

    代替授权公众号调用接口
    比如设置菜单,发送客服接口什么的功能,以前用的是access_token,现在改成authorizer_access_token便可以了

    报文加密解密
    公众号下可以选择是否使用安全模式,在开放平台强制进行加密解密处理,实现方式其实与公众平台的是一样的,所以有过这方面开放的可以直接复用

    全网发布
    按照上面的流程开发,如果全部实现完成,便可以进行全网发布流程,首先是自动化测试 
    这里面就涉及到了整个接入流程所有关键点,使用的是自动化测试,这里全部通过后提交人工审核,人工审核再通过就可以面向市场对所有的公众号进行接入了。

    原文:https://blog.csdn.net/goodzyw/article/details/47337039 

    展开全文
  • 微信第三方开放平台实战

    千人学习 2018-10-22 21:38:05
    本课程包括微信开放平台介绍,使用背景,平台申请,系统划分,系统架构搭建,中控服务平台搭建开放,公众号扫码绑定开发,卡卷强授权介绍(解决未认证公众号怎么玩卡卷问题),全网发布流程等等
  • 1、OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 允许用户提供一个令牌,而...

    1、OAuth2.0

      OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

      允许用户提供一个令牌而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。
    2、目标
      我们这里主要模拟使用OAuth2.0,用户通过扫描我们网页应用的二维码并进行授权登录来获取用户的基本信息的过程。详细的接口相关信息可以在微信开放平台上查看:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN
    3、前期准备(获取微信开发者权限)
      我们这里主要讲的是网站(Web)应用,网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统(即上面的协议)。在微信客户端授权登录(获取用户信息)的可以查看:http://www.cnblogs.com/0201zcr/p/5131602.html

      在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

    3.1、注册开发者账号
      可以在https://open.weixin.qq.com/ 这里申请开发的账号。由于是腾讯的网页,这里可以直接通过 QQ号进行登录。
    3.2、提交网站应用审核
      在已经登录的界面中选择“管理中心”——》网站应用——》创建网站应用
       将会弹出下面的界面
      填写过后,还有有一个页面需要填写,提交一份纸质版申请书扫描件(会提供模板,我们下载再来填写后,需盖章,签名),配置回调域名(扫码登录后会跳转的页面)等。
      之后提交审核即可,等微信审核通过,我们即可获得我们需要的网页应用的appid和AppSecret,并配置后回调的域名了(这三样是我们开发所必须的)。
    3.3、开发者资质认证
      由于我们这里要使用微信登录的接口,所以我们还需要向微信提出认证,只有认证了才能使用微信那些高级的接口。未认证的如下图所示
       认证之后是这样子的:
        我现在暂时没有找到可以向公众账号那样子的测试账号的申请。如果有知道怎么可以申请到测试账号的高手,希望能赐教一下。
      接下来,我们就可以开始我们的网页微信扫码登录开发了。
    4、授权流程说明
      微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。

      微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:

    1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
    2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
    3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

       获取access_token时序图:

     
    5、获取网页的二维码
      当我们通过微信的认证,获取到了appid和AppSecret,并配置了回调的域名。我们就已经可以获取属于我们网页的二维码了,获取的方式很简单,只需打开一个微信的链接,加上我们的appid和回调域名即可在网页上面打开二维码,用户用微信客户端扫码并授权登录之后即会跳转到我们配置的回调域名下。
    注意:
    1、这里填写的是域名(是一个字符串),而不是URL,因此请勿加http://等协议头;
    2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.comhttp://qq.com无法进行OAuth2.0鉴权

    5.1、请求url说明

      第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接:

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

     

     参数说明
    参数是否必须说明
    appid应用唯一标识(前面认证网页应用中获得)
    redirect_uri重定向地址,需要进行UrlEncode(前面认证网页应用中获得)
    response_type填code
    scope应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
    state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
     返回说明
       用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
    redirect_uri?code=CODE&state=STATE

       若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数

    redirect_uri?state=STATE

    5.2、事例:

      一号店的微信二维码链接如下:

    https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect

       将其复制到浏览器中打开即可获得一号店的二维码,二维码页面如下:

      通过使用微信客户端的扫一扫功能,扫描该二维码,即会跳转到上面填写redirect_uri所在的地址上。假如用户同意授权,这里就获得了微信返回的code参数了。

    6、获取用户信息

      假如前面已经获得code。我们可以通过code参数去获取用户openid和access_token,进而获得用户的信息。
    6.1、通过code参数获取access_token
    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

     参数说明

    参数是否必须说明
    appid应用唯一标识,在微信开放平台提交应用审核通过后获得
    secret应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
    code填写第一步获取的code参数
    grant_type填authorization_code
    返回说明

    正确的返回:

    复制代码
    { 
    "access_token":"ACCESS_TOKEN", 
    "expires_in":7200, 
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID", 
    "scope":"SCOPE",
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
    }
    复制代码
    参数说明
    access_token接口调用凭证
    expires_inaccess_token接口调用凭证超时时间,单位(秒)
    refresh_token用户刷新access_token
    openid授权用户唯一标识
    scope用户授权的作用域,使用逗号(,)分隔
     unionid当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。

    错误返回样例:

    {"errcode":40029,"errmsg":"invalid code"}
    注意
    • code参数的超时时间是5分钟,且每次请求的code参数的值都不一样。
    • access_token的超时时间是32分钟。
    6.2、通过access_token获取用户的基本信息
    获取的前提条件
    • access_token有效且为超时;
    • 微信用户已授权给第三方应用账号相应接口作用域(scope)【在二维码生成连接那里填写
    对于接口作用域(scope),能调用的接口有以下:
    授权作用域(scope)接口接口说明
    snsapi_base/sns/oauth2/access_token通过code换取access_token、refresh_token和已授权scope
    /sns/oauth2/refresh_token刷新或续期access_token使用
    /sns/auth检查access_token有效性
    snsapi_userinfo/sns/userinfo获取用户个人信息
     
      使用snsapi_base作用域的授权是扫码之后无需用户点击授权,扫码后直接跳转,用户感觉不到授权了,但这种授权方式能获取的数据量有限,这里我们要获取用户的基本信息,我们需要使用snsapi_userinfo授权。使用snsapi_userinfo授权,扫码后出现类似于下面的授权界面
      此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。请注意,在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况。
      
    https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID

     参数说明

    参数是否必须说明
    access_token调用凭证(上一个请求中获得)
    openid普通用户的标识,对当前开发者帐号唯一(上一个请求中获得)
           lang  否国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN
    返回说明

    正确的Json返回结果:

    复制代码
    { 
    "openid":"OPENID",
    "nickname":"NICKNAME",
    "sex":1,
    "province":"PROVINCE",
    "city":"CITY",
    "country":"COUNTRY",
    "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
    "privilege":[
    "PRIVILEGE1", 
    "PRIVILEGE2"
    ],
    "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
    
    }
    复制代码
    参数说明
    openid普通用户的标识,对当前开发者帐号唯一
    nickname普通用户昵称
    sex普通用户性别,1为男性,2为女性
    province普通用户个人资料填写的省份
    city普通用户个人资料填写的城市
    country国家,如中国为CN
    headimgurl用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
    privilege用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
    unionid用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。

    错误的Json返回示例:

    { 
    "errcode":40003,"errmsg":"invalid openid"
    }

    7、总结 

      最近着手开发了微信网页扫码登录和公众号授权登录收获颇丰,两者的开发很类似。以下是我个人摸索过程中发现的两者的异同:

    • 两者都可以通过微信客户端扫码授权的方式,让第三方页面获得微信用户的一些基本信息(昵称、性别、所在地、在微信唯一标示等……)。他们都是通过提供一个链接让用户授权的方式。但网页版需要在页面打开二维码之后授权,而公众号则需要用户先关注了我们的公众号,然后点开公众号里面的链接,确认授权即可。
    • 网页扫码登录需要将授权的链接(二维码链接)在网页中打开、而公众号授权登录的链接必须要微信客户端中打开。
    • 无论网页扫码登录还是在公众号中授权登录,都是通过授权的方式获得一个code参数,之后通过code参数获取access_token和openid和通过access_token和openid去获取用户的基本信息的请求链接是一样的。
    • 在开发公众号授权登录的过程中,我发现了有测试账号的提供,足以满足我们的测试和开发,但在开发网页扫码时,暂时未发现哪里能获取测试账号,我是通过申请获取的。(希望知道哪里有测试账号的请求高手赐教)。

     公众账号授权登录:http://www.cnblogs.com/0201zcr/p/5131602.html

    微信公众号群发消息:http://www.cnblogs.com/0201zcr/p/5866296.html

       致谢:感谢您的阅读!
    展开全文
  • 官方文档介绍的很详细,下面是看到的一篇博客,很有帮助,感谢! ... 据微信开放平台“开发资源”中网站应用微信登陆功能开发指南描述:进行授权登陆接入前,需要先注册一个开发者账号,并拥有一个已经审核通过的网站...

    官方文档介绍的很详细,下面是看到的一篇博客,很有帮助,感谢!

    原文:https://blog.csdn.net/qq_34190023/article/details/81133619 

    据微信开放平台“开发资源”中网站应用微信登陆功能开发指南描述:进行授权登陆接入前,需要先注册一个开发者账号,并拥有一个已经审核通过的网站应用,并获取AppID和APPSecret,然后申请微信登陆并通过审核后,可以接入流程进行开发。

    据开发者资质认证处介绍:开发者资质认证通过后,微信开放平台帐号下的应用,将获得微信登录、智能接口、第三方平台开发等高级能力。

    所以在微信第三方授权登陆获取用户信息开发前,需要做一些前期准备。目的是获取到AppID以及AppSecret,并成功申请微信登陆功能。

    一、前期准备流程
    1、注册邮箱账号。

    2、根据邮箱账号注册微信开放平台账号,完善开发者资料。

    3、申请开发者资质认证、填写相关资料、填写发票、支付认证金额。提交并等待认证结果

    4、认证成功后,创建网站应用,填写基本信息、下载网站信息登记表填写并上传扫描件、填写授权回调域等。提交审核等待结果。

    5、认证成功后,创建移动应用,至少选择安卓、IOS、WP8其中一种平台

    6、创建应用成功后,申请微信登陆,等待审核结果,待审核通过后,可进行微信登陆的开发。

    注:创建应用和开发者资质认证可同时进行

     

    准备工作大致流程图

    二、具体实现步骤
    1、注册邮箱账号
    支持网易邮箱、QQ邮箱等常规邮箱。此邮箱将成为日后登陆开放平台的账号。

     

    2、注册微信开放平台账号、完善开发者资料
    1)填写邮箱进行注册、开放平台将发送邮件到填写邮箱中,点击邮件上的地址进行开发者资料的完善。(开放平台注册地址:https://open.weixin.qq.com/cgi-bin/readtemplate?t=regist/regist_tmpl&lang=zh_CN )

    2)开发者资料完善:主要填写注册人信息。如真实姓名、真实手机号码、联系地址、身份证号码。使用注册人的微信扫码绑定为管理员。提交信息。(邮件信息包含地址,点击后进行资料完善)

    3)完善资料后,根据邮箱及密码进行登录

     

    3、申请开发者资质认证
    1)申请开发者资质认证
    登录后,点击右上角邮箱号进入“基本资料”,点击“开发者资质认证”,显示未认证,点击“现在申请”。

    认证成功后,这里将变成认证成功:

    认证成功后,这里将变成认证成功:

    2)选定类型


    同意“微信开放平台开发者资质认证服务协议”,点击下一步。选择类型为“企业”,点击确定。

    注:类型包含了企业、网店商家、媒体(事业单位媒体、其他媒体)、政府及事业单位、其他组织(社会团体、民办非企业、其他组织)

    3)填写“认证资料”
    包括企业全称、组织机构代码、工商执照注册号、法定代表人/企业负责人姓名、经营范围(一般经营范围)、企业规模(选填)、企业开户名称、企业开户银行、企业银行账号。

    4)填写“管理员信息”
    包括账号管理员姓名、账号管理员部门与职位、账号管理员手机号、管理员座机、管理员电子邮件、身份证号。最后需要使用管理员的微信进行扫码。

    5)上传“企业基本信息”材料:
    需要准备的材料及要求如下

    I.组织机构代码证

    组织机构代码证必须在有效期范围内。必须是原件照片、扫描件或复印件加盖企业公章后的扫描件。图片不超2M

    II.企业工商营业执照

    中国大陆工商局或市场监督管理局颁发的工商营业执照,且必须在有效期内。要求原件照片、扫描件或者复印件加盖企业公章后的扫描件

    III.申请公函下载打印

    如果是一般企业需要先下载“一般企业申请认证公函”,个体下载“个体工商户申请认证公函”(见附件中“一般企业申请认证公函.doc”及“个体工商户申请认证公函.doc”或于网站中下载)。对下载的申请公函进行打印。

    IV.填写申请公函信息

    填写内容主要有(根据不同企业类型进行填写,只需要填写其中一个就可以):

    A.一般企业申请认证公函:

    a.企业信息:申请企业全称、官网(可缺省)、办公电话、办公地址、企业规模、企业简介(要说明企业经营范围,重要历程,主要产品和服务及覆盖区域等事项)、

    b.法定代表信息:法定代表人姓名、身份证号码、应用的Appid(这时还没有Appid,此项不填)、登陆Email、

    c.申请相关信息:申请认证理由、提供的服务、

    d.账号运营者信息 : 账号运营者姓名、部门及职位、身份证号、手机号、办公联系电话、电子邮箱

    e.填写认证申请公函:最后运营者签字并加盖企业章

    B.个体工商户申请认证公函:

    a.个体工商户信息:个体工商户全称、官网(可缺省)、办公电话、办公地址、规模、简介(主要说明经营范围,重要历程,主要产品和服务及覆盖区域等事项)

    b.经营者信息:经营者姓名、身份证号码、应用的Appid(这时还没有Appid,此项不填)、登陆Email

    c.申请相关信息:申请认证理由、提供的服务、

    d.账号运营者信息:账号运营者姓名、部门及职位、身份证号、手机号、办公联系电话、电子邮箱

    e.填写认证申请公函:最后运营者签字并加盖企业章

    V.对填写好的申请公函进行上传图片:

    上传加盖企业公章的原件照片或扫描件

    点击下一步。

    6)进入填写发票及支付费用
    等待认证结果。

    注:开发者认证费用为300.有效期一年,可在最后三个月申请年审续期

     

    4、创建应用
    1)创建网站应用
    进入开放平台首页(https://open.weixin.qq.com),点击上方“管理中心”,点击“网站应用”,点击“创建网站应用”

    I.填写基本信息

    包括网站应用名称、英文名(选填)、应用简介、英文简介(选填)、应用官网。

    II.上传网站信息登记表扫描件及网站应用图片

           A. 网站信息登记表

    先下载《微信开放平台网站信息登记表》(见附件”微信开放平台网站信息登记表.doc”).然后进行填写打印。最后盖章,上传扫描件。图片不超过2M

    网站开放平台信息登记表填写内容包括:

    a. 网站信息:

    1)网站网址:要创建第三方准备使用的网址。

    2)网站备案号/许可证号

    3)主板单位名称/个人姓名

    4)单位/个人官网网址

    5)单位/个人所在地: 

    6)单位/个人简介:

    b. 开发者账户信息

    1)邮箱:注册微信开放平台的注册邮箱

    2)网站应用名称:与开放平台填写的网站应用名称一致

    c. 负责人信息

    1)  姓名

    2)  职务

    3)  联系人手机

    4)  责任人个人邮箱

    然后填写责任人签名。职务。以及填写日期,最后盖上申请公司的章

           B. 网站应用图片

    上传网站应用水印招聘。28*28像素以及108*108像素的png图片,大小不超过300k。

    上传完成后,点击下一步

    III.填写授权回调域

    填写合法的域名。第三方授权登陆后,只能回调到该域名下的页面。(即,开发的网站上线后的域名)

    审核时间大概7个工作日内(审核资料完整正确的话,大概3天左右能审核通过)

    审核不通过的话,会显示驳回,并且告知哪个环节审核不通过,可以重新修改再审,

    审核成功页面:

    2)创建移动应用
    进入开放平台首页(https://open.weixin.qq.com),点击上方“管理中心”,点击“移动应用”,点击“创建移动应用”

    I.填写基本信息

    包括移动应用名称、英文名(选填)、应用简介、英文简介(选填)、应用官网。

    II.上传移动应用图片

        上传移动应用水印图片28*28像素的png图片,以及移动应用高清图片108*108像素的png图片。大小均不超过300k

    III.填写平台信息

         选择平台,一共有三种平台:ISO应用、Android应用和WP8应用

         至少选择一个平台,可以多选。

    A. IOS应用

           细分为iPhone和iPad,可多选

           这两种设备类型均需要提供“Bundle ID”(ISO应用唯一标识)、“测试版本Bundle ID”(ISO应用测试版本的BundleID)、“AppStore下载地址”(选填)

    B.Android应用

            需要提供 “应用签名” 和 “应用包名”,以及“应用下载地址(选填)”

         应用签名可以使用签名生成工具直接从安装当前应用的手机获取,应用签名由开发者签名该应用的keystore文件决定

         应用包名在manifest文件里声明,要和正式发布应用的包名一致。

    C.WP8 应用

            WP8应用只需要填写“应用下载地址(选填)”就可以了。

    注意:应用若还没有提交到应用市场,下载地址等可以暂时为空,提交到应用市场后,可修改下载地址。

     

    注:

    1.审核将在三个工作日内完成,目前只审核开发者的资质和真实性,不涉及应用内容本部,不需要开发者提交ipa文件或将含微信SDK的版本在AppStore上线后再审核,但要求开发者提供该应用已经上线的版本的下载地址

    2.同一应用在不同平台的版本应共用一个AppID

    审核成功后的页面(Android)

    5、申请微信登陆功能
    成功创建应用并审核通过后,点击应用右方“查看”可以查看应用详情。

    在“接口信息”一栏中,查看当前应用拥有的接口权限。

    选中“微信登陆”接口,点击右方申请开通,开通微信登陆功能。

     

    三、注意事项
    1、开发者资质认证结果只有成功或失败两种情况。审核费用与最终是否审核通过无关。每申请一次,就需要支付一次审核服务费用

    2、我方在完成在线申请及资料提交流程,并完成审核服务费用支付后,腾讯会在15个工作日内展开认证工作,我方应积极配合腾讯及第三方审核公司的认证需求,并有权随时了解、查询认证进度

    3.认证失败原因可能情况:

    1)由于我方原因,经腾讯三次系统通知用户调整申请内容,我方仍未能满足开发者资质认证要求的;

    2)由于我方原因:自用户付费之日起三十日,我方仍未能满足开发者资质认证要求之一;

    3)因其他原因而不能认证成功的情形

    4、网站应用和移动应用一个开发者最多只能登记10个。

     

    四.主要提供材料
    主要提供材料,详情见“具体实现步骤”

    微信开放平台登陆邮箱
    开发者个人详细信息
    企业信息及法人(负责人)信息(包括官网等)
    企业账号管理员信息(包括微信扫码)
    企业章
    应用官网及备案号/许可证。 应用图标。

    五、特殊情况处理方案
    1.若我方向腾讯或者第三方审核机构提供的资料和信息如有变更的,应当及时采取以下措施:

    1)如处于认证过程中的资料和信息发生变更,用户应立即通知腾讯或负责认证订单的第三方审核机构更新有关资料及信息;

    2)如认证成功后资料和信息发生变更,用户应及时申请补充订单变更有关资料及信息;

    3)如认证成功后腾讯发现资料和信息存在错误,用户应及时申请补充订单更正有关资料及信息。


     

    展开全文
  • 微信小程序授权微信开放平台

    千次阅读 2019-06-30 13:18:26
    这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、...

    开放平台注册

    开发第三方平台,首先需要到微信开放平台申请注册第三方平台账号

    创建第三方平台

    在这里插入图片描述

    第三方平台信息配置

    在这里插入图片描述

    第三方授权流程

    详细流程说明可参照官网授权流程技术说明
    在这里插入图片描述

    授权流程代码

    获取第三方平台接口调用凭据“component_verify_ticket”

    出于安全考虑,在第三方平台创建审核通过后,微信服务器 每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据。

    package com.litte.controller.warrant;
    
    import com.litte.entity.reception.TWarrantInfo;
    import com.litte.service.warrantinfo.TWarrantInfoService;
    import com.litte.service.warrantmerchant.TWarrantMerchantService;
    import com.litte.util.DateUtil;
    import com.litte.util.WinxinUtil;
    import net.sf.json.JSONObject;
    import org.apache.commons.lang.StringUtils;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Calendar;
    import java.util.Date;
    
    @Controller
    @RequestMapping("/warrant")
    public class WarrantController {
        private static final Logger LOGGER = LoggerFactory.getLogger(WarrantController.class);
        //公众号第三方平台的appid
        private static final String APPID = "wx9681884b28ed7927";
        //第三方平台申请时填写的接收消息的校验token
        private static final String TOKEN = "xinxingshang";
        //    private static final String TOKEN = "xinxingshangstar";
        //第三方平台申请时填写的接收消息的加密symmetric_key
        private static final String ENCODINGAESKEY = "xinxingshangstarkeykey11keyxinxingshangstar";
        private static final String SECRET = "a4d75ccc5b9ca0cef697116bc8c2e156";
        //获取"component_access_token"URL
        private static final String COMPONENT_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";
        // 获取"pre_auth_code"URL
        private static final String PRE_AUTH_CODE = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token=componentAccessToken";
        // 刷新令牌
        private static final String AUTHORIZER_REFRESH_TOKEN = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token?component_access_token=componentAccessToken";
    
        @Autowired
        TWarrantInfoService tWarrantInfoService;
        @Autowired
        TWarrantMerchantService TWarrantMerchantService;
    
        /**
         * 获取"component_verify_ticket"
         *
         * @Description:
         * @Author: Mr.Jkx
         * @Date: 2019/4/3 16:03
         * 参考链接:https://blog.csdn.net/liaoyundababe/article/details/53537417
         * https://blog.csdn.net/zhangdaiscott/article/details/48269837
         */
        @RequestMapping("/responseRequest")
        @ResponseBody
        public void responseRequest(HttpServletRequest request, HttpServletResponse response) throws AesException, IOException {
            LOGGER.info("WeChat third-party platform --------- WeChat push Ticket message 10 minutes-----------");
            output(response, "success"); // 输出响应的内容。
            processAuthorizeEvent(request);
        }
    
        /**
         * 处理授权事件的推送
         *
         * @param request
         * @throws IOException
         * @throws AesException
         * @throws DocumentException
         */
        public void processAuthorizeEvent(HttpServletRequest request)
                throws IOException, AesException {
            String nonce = request.getParameter("nonce");
            String timestamp = request.getParameter("timestamp");
            String msgSignature = request.getParameter("msg_signature");
            LOGGER.info("=====WeChat third-party platform======" + nonce + "  " + timestamp + "  " + msgSignature);
            StringBuilder sb = new StringBuilder();
            BufferedReader in = request.getReader();
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            String xml = sb.toString();
            LOGGER.info("Third-party platform is released on the whole network-----------------------original, Xml=" + xml);
            WXBizMsgCrypt pc = new WXBizMsgCrypt(TOKEN, ENCODINGAESKEY, APPID);
            LOGGER.info("Third-party platform is released on the whole network-----------------------decryption WXBizMsgCrypt new 成功");
            String xml1 = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
            LOGGER.info("Third-party platform is released on the whole network-----------------------After decryption, Xml=" + xml1);
            processAuthorizationEvent(xml1);
        }
    
        /**
         * 保存componentVerifyTicket
         *
         * @param xml
         */
        void processAuthorizationEvent(String xml) {
            Document doc;
            try {
                doc = DocumentHelper.parseText(xml);
                Element rootElt = doc.getRootElement();
                String componentVerifyTicket = rootElt.elementText("ComponentVerifyTicket");
                LOGGER.info("Third-party platform is released on the whole network---------After decryption, ComponentVerifyTicket=" + componentVerifyTicket);
                if (StringUtils.isNotBlank(componentVerifyTicket)) {
                    TWarrantInfo tWarrantInfo = new TWarrantInfo();
                    tWarrantInfo.setId("053882ef3bed46c795bbd7da470e79cf");
                    tWarrantInfo.setComponentVerifyTicket(componentVerifyTicket);
                    tWarrantInfo.setTicketCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                    int i = tWarrantInfoService.updateByPrimaryKeySelective(tWarrantInfo);
                    if (i > 0) {
                        LOGGER.info("WeChat third-party platform------------component_verify_ticket data save success");
                    } else {
                        LOGGER.info("WeChat third-party platform------------component_verify_ticket data save failure");
                    }
                }
            } catch (DocumentException e) {
                e.printStackTrace();
            }
        }
    
        /**
        * @Description: 第三方平台全网发布,消息与事件接收URL
        * @Author: Mr.Jkx
        * @Date: 2019/5/8 18:10
        */
        @RequestMapping(value = "/$APPID$/xxsCallback")
        public void acceptMessageAndEvent(HttpServletRequest request, @PathVariable("APPID") String appid,
                                          HttpServletResponse response) throws IOException, DocumentException, AesException {
            LOGGER.info("第三方平台全网发布---------{appid}/callback---------验证开始。。。。");
            String msgSignature = request.getParameter("msg_signature");
            LOGGER.info("第三方平台全网发布-------------{appid}/callback-----------验证开始。。。。msg_signature=" + msgSignature);
            if (!StringUtils.isNotBlank(msgSignature)) {
                return;// 微信推送给第三方开放平台的消息一定是加过密的,无消息加密无法解密消息
            }
            StringBuilder sb = new StringBuilder();
            BufferedReader in = request.getReader();
            String line;
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            in.close();
    
            String xml = sb.toString();
            Document doc = DocumentHelper.parseText(xml);
            Element rootElt = doc.getRootElement();
            String toUserName = rootElt.elementText("ToUserName");
    
            //微信全网测试账号
    //        if (StringUtils.equalsIgnoreCase(toUserName, APPID)) {
            LOGGER.info("全网发布接入检测消息反馈开始---------------APPID=" + appid + "------------------------toUserName=" + toUserName);
            checkWeixinAllNetworkCheck(request, response, xml);
    //        }
        }
    
        public void checkWeixinAllNetworkCheck(HttpServletRequest request, HttpServletResponse response,String xml) throws DocumentException, AesException, IOException {
            String nonce = request.getParameter("nonce");
            String timestamp = request.getParameter("timestamp");
            String msgSignature = request.getParameter("msg_signature");
    
            WXBizMsgCrypt pc = new WXBizMsgCrypt(TOKEN, ENCODINGAESKEY, APPID);
            xml = pc.decryptMsg(msgSignature, timestamp, nonce, xml);
    
            Document doc = DocumentHelper.parseText(xml);
            Element rootElt = doc.getRootElement();
            String msgType = rootElt.elementText("MsgType");
            String toUserName = rootElt.elementText("ToUserName");
            String fromUserName = rootElt.elementText("FromUserName");
    
            LOGGER.info("---全网发布接入检测--step.1-----------msgType="+msgType+"-----------------toUserName="+toUserName+"-----------------fromUserName="+fromUserName);
    //        LogUtil.info("---全网发布接入检测--step.2-----------xml="+xml);
            if("event".equals(msgType)){
    //           LogUtil.info("---全网发布接入检测--step.3-----------事件消息--------");
                String event = rootElt.elementText("Event");
                replyEventMessage(request,response,event,toUserName,fromUserName);
            }else if("text".equals(msgType)){
    //           LogUtil.info("---全网发布接入检测--step.3-----------文本消息--------");
                String content = rootElt.elementText("Content");
                processTextMessage(request,response,content,toUserName,fromUserName);
            }
        }
    
        public void replyEventMessage(HttpServletRequest request, HttpServletResponse response, String event, String toUserName, String fromUserName) throws DocumentException, IOException {
            String content = event + "from_callback";
    //        LogUtil.info("---全网发布接入检测------step.4-------事件回复消息  content="+content + "   toUserName="+toUserName+"   fromUserName="+fromUserName);
            replyTextMessage(request,response,content,toUserName,fromUserName);
        }
    
        public void processTextMessage(HttpServletRequest request, HttpServletResponse response,String content,String toUserName, String fromUserName) throws IOException, DocumentException{
            if("TESTCOMPONENT_MSG_TYPE_TEXT".equals(content)){
                String returnContent = content+"_callback";
                replyTextMessage(request,response,returnContent,toUserName,fromUserName);
            }else if(StringUtils.startsWithIgnoreCase(content, "QUERY_AUTH_CODE")){
                output(response, "");
                //接下来客服API再回复一次消息
                replyApiTextMessage(request,response,content.split(":")[1],fromUserName);
            }
        }
    
        /**
         * 回复微信服务器"文本消息"
         * @param request
         * @param response
         * @param content
         * @param toUserName
         * @param fromUserName
         * @throws DocumentException
         * @throws IOException
         */
        public void replyTextMessage(HttpServletRequest request, HttpServletResponse response, String content, String toUserName, String fromUserName) throws DocumentException, IOException {
            Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
            StringBuffer sb = new StringBuffer();
            sb.append("<xml>");
            sb.append("<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>");
            sb.append("<FromUserName><![CDATA["+toUserName+"]]></FromUserName>");
            sb.append("<CreateTime>"+createTime+"</CreateTime>");
            sb.append("<MsgType><![CDATA[text]]></MsgType>");
            sb.append("<Content><![CDATA["+content+"]]></Content>");
            sb.append("</xml>");
            String replyMsg = sb.toString();
    
            String returnvaleue = "";
            try {
                WXBizMsgCrypt pc = new WXBizMsgCrypt(TOKEN, ENCODINGAESKEY, APPID);
                returnvaleue = pc.encryptMsg(replyMsg, createTime.toString(), "easemob");
    //            LOGGER.info("------------------加密后的返回内容 returnvaleue: "+returnvaleue);
            } catch (AesException e) {
                e.printStackTrace();
            }
            output(response, returnvaleue);
        }
    
        public void replyApiTextMessage(HttpServletRequest request, HttpServletResponse response, String auth_code, String fromUserName) throws DocumentException, IOException {
            // 得到微信授权成功的消息后,应该立刻进行处理!!相关信息只会在首次授权的时候推送过来
            LOGGER.info("------step.1----使用客服消息接口回复粉丝----逻辑开始-----------------");
            try {
                LOGGER.info("------step.1----使用客服消息接口回复粉丝----逻辑开始-------------auth_code: "+auth_code+"  thirdWeixinService.getComponent_access_token:"+TOKEN);
                String url = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token="+TOKEN;
                JSONObject jsonObject1 = new JSONObject();
                jsonObject1.put("component_appid", APPID);
                jsonObject1.put("authorization_code", auth_code);
                JSONObject jsonRes = WinxinUtil.doPostStr(url, jsonObject1.toString());
                LOGGER.info("------step.1----使用客服消息接口回复粉丝----逻辑开始---------------------jsonRes:"+jsonRes.toString());
    
                String msg = auth_code + "_from_api";
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("touser", fromUserName);
                jsonObject.put("msgtype", "text");
                JSONObject text = new JSONObject();
                text.put("content", msg);
                jsonObject.put("text", text);
                WinxinUtil.doPostStr("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+TOKEN, jsonObject.toString());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 工具类:回复微信服务器"文本消息"
         * @param response
         * @param returnvaleue
         */
        public void output(HttpServletResponse response, String returnvaleue) {
            try {
                PrintWriter pw = response.getWriter();
                pw.write(returnvaleue);
                pw.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    获取第三方平台“component_access_token”

    第三方平台通过自己的component_appid(即在微信开放平台管理中心的第三方平台详情页中的AppID和AppSecret)和component_appsecret,以及component_verify_ticket(每10分钟推送一次的安全ticket)来获取自己的接口调用凭据(component_access_token)

    /**
         * @Description: “component_access_token”获取
         * 有效期2小时
         * @Author: Mr.Jkx
         * @Date: 2019/4/19 16:57
         * SpringBoot定时任务,每个110分钟获取一次,并保存到数据库
         */
        @Scheduled(fixedRate = 6600000)
        public void getComponentAccessToken() {
            System.out.println("-------------get component_access_token---------------");
            WarrantController warrantController = new WarrantController();
            try {
                // 从数据库获取微信推送的“component_verify_ticket”
                TWarrantInfo tWarrantInfo = tWarrantInfoService.selectByPrimaryKey("053882ef3bed46c795bbd7da470e79cf");
                String componentVerifyTicket = tWarrantInfo.getComponentVerifyTicket();
    
                // 根据“componentVerifyTicket”获取“component_access_token”
                String componentAccessToken = getComponentAccessToken(componentVerifyTicket);
    
                // 数据库保存微信推送加密信息“component_access_token”
                TWarrantInfo tWarrantInfoData = new TWarrantInfo();
                tWarrantInfoData.setComponentAccessToken(componentAccessToken);
                editWarrantInfo(tWarrantInfoData);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * @Description: 编辑授权信息
         * @Author: Mr.Jkx
         * @Date: 2019/4/20 10:12
         */
        public void editWarrantInfo(TWarrantInfo tWarrantInfo) {
            tWarrantInfo.setId("053882ef3bed46c795bbd7da470e79cf");
            if (StringUtils.isNotBlank(tWarrantInfo.getComponentAccessToken())) {
                tWarrantInfo.setTokenCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
            }
            if (StringUtils.isNotBlank(tWarrantInfo.getPreAuthCode())) {
                tWarrantInfo.setCodeCreateTime(DateUtil.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
            }
            int i = tWarrantInfoService.updateByPrimaryKeySelective(tWarrantInfo);
            if (i > 0) {
                LOGGER.info("WeChat third-party platform------------data save success");
            } else {
                LOGGER.info("WeChat third-party platform------------data save failure");
            }
        }
    
    	/**
         * @Description: 获取"component_access_token"
         * @Author: Mr.Jkx
         * @Date: 2019/4/9 9:45
         */
        public String getComponentAccessToken(String componentVerifyTicket) throws IOException {
            /**拼装待发送的Json*/
            JSONObject json = new JSONObject();
            json.accumulate("component_appid", APPID);
            json.accumulate("component_appsecret", SECRET);
            json.accumulate("component_verify_ticket", componentVerifyTicket);
            LOGGER.info("第三方授权:获取component_access_token:getComponentAccessToken:请求参数json={}", json);
            /**发送Https请求到微信*/
            JSONObject retJSONObject = WinxinUtil.doPostStr(COMPONENT_TOKEN_URL, json.toString());
            String component_access_token = retJSONObject.getString("component_access_token");
            LOGGER.info("第三方授权:获取component_access_token回执数据:getComponentAccessToken:component_access_token={}", component_access_token);
    
            return component_access_token;
        }
    

    获取预授权码“pre_auth_code”

    第三方平台通过自己的接口调用凭据(component_access_token)来获取用于授权流程准备的预授权码(pre_auth_code)

    /**
         * @Description: 获取预授权码“pre_auth_code”
         * 有效期10分钟
         * @Author: Mr.Jkx
         * @Date: 2019/4/19 16:57
         * SpringBoot定时任务,每隔9分钟获取一次,并保存到数据库
         */
        @Scheduled(fixedRate = 540000)
        public void getpreAuthCode() {
            System.out.println("---------------get pre_auth_code-------------");
            WarrantController warrantController = new WarrantController();
            try {
                // 从数据库获取“component_access_token”令牌
                TWarrantInfo tWarrantInfo = tWarrantInfoService.selectByPrimaryKey("053882ef3bed46c795bbd7da470e79cf");
                String component_access_token = tWarrantInfo.getComponentAccessToken();
    
                // 根据“component_access_token”获取“pre_auth_code”
                String preAuthCodeData = getPreAuthCodeData(component_access_token);
    
                // 数据库保存预授权码“pre_auth_code”
                TWarrantInfo tWarrantInfoData = new TWarrantInfo();
                tWarrantInfoData.setPreAuthCode(preAuthCodeData);
                editWarrantInfo(tWarrantInfoData);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    	/**
         * @Description: 获取"pre_auth_code"(预授权码)
         * @Author: Mr.Jkx
         * @Date: 2019/4/9 10:21
         */
        public String getPreAuthCodeData(String component_access_token) throws IOException {
            JSONObject json = new JSONObject();
            json.accumulate("component_appid", APPID);
            json.accumulate("component_access_token", component_access_token);
            String url = PRE_AUTH_CODE.replace("componentAccessToken", component_access_token);
            /**发送Https请求到微信*/
            JSONObject retStr = WinxinUtil.doPostStr(url, json.toString());
            LOGGER.info("第三方授权:ThirdPartyServiceImpl:getPreAuthCode:retStr={}", retStr);
            JSONObject retJSONObject = JSONObject.fromObject(retStr);
            /**在返回结果中获取pre_auth_code*/
            String pre_auth_code = retJSONObject.getString("pre_auth_code");
            LOGGER.info("==========第三方授权:获取pre_auth_code:{}", pre_auth_code);
            return pre_auth_code;
        }
    

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

    通过授权码和自己的接口调用凭据(component_access_token),换取公众号或小程序的接口调用凭据(authorizer_access_token和用于前者快过期时用来刷新它的authorizer_refresh_token)和授权信息(授权了哪些权限等信息)

    /**
         * @Description: 刷新令牌“authorizer_refresh_token”
         * 有效期2小时
         * @Author: Mr.Jkx
         * @Date: 2019/4/19 16:57
         */
        @Scheduled(fixedRate = 6600000)
        public void refreshAuthorizerRefreshToken() {
            System.out.println("---------------get authorizer_refresh_token-------------");
            WarrantController warrantController = new WarrantController();
            try {
                // 授权方appid{},接口调用凭据刷新令牌查询
                List<TWarrantMerchant> tWarrantMerchantList = TWarrantMerchantService.selTWarrantMerchant();
                // 从数据库获取“component_access_token”令牌
                TWarrantInfo tWarrantInfo = tWarrantInfoService.selectByPrimaryKey("053882ef3bed46c795bbd7da470e79cf");
                String component_access_token = tWarrantInfo.getComponentAccessToken();
                List<TWarrantMerchant> tWarrantMerchants = refreshAuthorizerRefreshToken(tWarrantMerchantList, component_access_token);
    
                if (tWarrantMerchants.size() > 0) {
                    for (TWarrantMerchant tWarrantMerchant : tWarrantMerchants) {
                        long currentTime = new Date().getTime() + 120 * 60 * 1000;
                        Date date = new Date(currentTime);
                        tWarrantMerchant.setDeadline(date);
                        TWarrantMerchantService.updTWarrantMerchant(tWarrantMerchant);
                    }
                } else {
                    System.out.println("---------------No authorizer_refresh_token needs to updated-------------");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    	/**
         * @Description: 刷新令牌“authorizer_refresh_token”
         * @Author: Mr.Jkx
         * @Date: 2019/5/6 17:58
         */
        public List<TWarrantMerchant> refreshAuthorizerRefreshToken(List<TWarrantMerchant> tWarrantMerchants, String component_access_token) throws IOException {
            List<TWarrantMerchant> tWarrantMerchantList = new ArrayList<>();
            // 查找需要刷新令牌的数据
            for (TWarrantMerchant tWarrantMerchant : tWarrantMerchants) {
    //            Date deadline = tWarrantMerchant.getDeadline();
    //            if (deadline.getTime() - new Date().getTime() < 600000) {
                    tWarrantMerchantList.add(tWarrantMerchant);
    //            }
            }
            // 重新获取令牌
            List<TWarrantMerchant> authorizerRefreshToken = getAuthorizerRefreshToken(tWarrantMerchantList, component_access_token);
            return authorizerRefreshToken;
        }
    
        /**
         * @Description: 重新获取令牌
         * @Author: Mr.Jkx
         * @Date: 2019/5/6 18:39
         */
        private List<TWarrantMerchant> getAuthorizerRefreshToken(List<TWarrantMerchant> tWarrantMerchantList, String component_access_token) throws IOException {
            List<TWarrantMerchant> tWarrantMerchants = new ArrayList<>();
            for (TWarrantMerchant tWarrantMerchant : tWarrantMerchantList) {
                JSONObject json = new JSONObject();
                json.accumulate("component_appid", APPID);
                json.accumulate("authorizer_appid", tWarrantMerchant.getAuthorizationAppid());
                json.accumulate("authorizer_refresh_token", tWarrantMerchant.getAuthorizerRefreshToken());
    
                /**发送Https请求到微信*/
                String url = AUTHORIZER_REFRESH_TOKEN.replace("componentAccessToken", component_access_token);
                JSONObject retStr = WinxinUtil.doPostStr(url, json.toString());
                LOGGER.info("==========第三方授权: 令牌刷新{}", retStr);
    
                JSONObject retJSONObject = JSONObject.fromObject(retStr);
                /**在返回结果中获取pre_auth_code*/
                LOGGER.info("==========第三方授权:令牌刷新:{}", retJSONObject);
    
                String authorizer_refresh_token = retJSONObject.getString("authorizer_refresh_token");// 接口调用凭据刷新令牌
                String authorizer_access_token = retJSONObject.getString("authorizer_access_token");// 小程序授权令牌
                LOGGER.info("==========第三方授权:获取到的新令牌:{}", retJSONObject);
    
                // 授权商户信息保存
                TWarrantMerchant updTWarrantMerchant = new TWarrantMerchant();
                updTWarrantMerchant.setId(tWarrantMerchant.getId());
                // 接口调用凭据刷新令牌
                updTWarrantMerchant.setAuthorizerRefreshToken(authorizer_refresh_token);
                updTWarrantMerchant.setAuthorizerAccessToken(authorizer_access_token);
                tWarrantMerchants.add(updTWarrantMerchant);
            }
            return tWarrantMerchants;
        }
    

    触发授权页面

    准备好授权所需的必要信息,请求授权页面,扫码授权。
    在这里插入图片描述

    页面js实现

    // 页面授权完成跳转页面“https://www.xxxxx.com/xxx/pages/set1.html”
    $(function(){
                $("#bingLink").click(function(){
                	// 请求获取必要信息
                    postCreaterHttp('/warrantPhone/warrantMessage',{},function(res){
                        if("200" == res.errorCode){
                            var url='https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='+res.message.componentAppid+'&pre_auth_code='+res.message.preAuthCode+'&redirect_uri=https://www.xxxxx.com/xxx/pages/set1.html';
                            window.open(url);// 请求授权页面
                        }else if("300" == res.errorCode){
                            layui.use('layer', function() {
                                var layer = layui.layer;
                                layer.msg("账号已经绑定【" + res.appletsName + "】");
                            })
                        }
                    })
                })
    
            })
    

    后台接口实现

    @RequestMapping("warrantPhone")
    @Controller
    public class WarrantPhoneController {
        // 第三方appid
        private static final String COMPONENT_APPID = "wx9681884b28ed7927";
        //回调地址,此处没有用到
        private static final String REDIRECT_URI = "https://www.xinxingshangstar.com/warrant/warrantBack";
    
        @Autowired
        TWarrantInfoMapper tWarrantInfoMapper;
        @Autowired
        TWarrantMerchantMapper tWarrantMerchantMapper;
    
    	/**
    	* @Description: 查询为授权准备的信息
    	* @Author:      Mr.Jkx
    	* @UpdateDate:  2019/5/10 15:44
    	*/
        @RequestMapping("/warrantMessage")
        @ResponseBody
        public Map<String, Object> getWarrantMessageByPhone(TWarrantMerchant tWarrantMerchant){
            Map<String, Object> resMap = new HashMap<>();
            // 根据授权方APPID查询此商户是否授权
            TWarrantMerchant tWarrantMerchantData = tWarrantMerchantMapper.selWarrantMerchant(tWarrantMerchant);
            if(null == tWarrantMerchantData){
                // 数据库查询授权信息
                TWarrantInfo warrantMessageByPhone = tWarrantInfoMapper.selectByPrimaryKey("053882ef3bed46c795bbd7da470e79cf");
                warrantMessageByPhone.setComponentAppid(COMPONENT_APPID);
                warrantMessageByPhone.setRedirectUri(REDIRECT_URI);
                resMap.put("errorCode", "200");
                resMap.put("message", warrantMessageByPhone);
                resMap.put("appletsName", "");
            }else{
                resMap.put("errorCode", "300");
                resMap.put("message", JsonUtil.toJsonString(new TWarrantInfo()));
                resMap.put("appletsName", tWarrantMerchantData.getNickName());
            }
            return resMap;
        }
    }
    

    在这里插入图片描述

    授权完成根据“authCode”(授权码)请求获取授权信息

    请求获取授权信息,及授权小程序信息;

    本项目,前端js实现

        $(function () {
            var src = window.location.href;
            var num = 5
            if (src.indexOf("?auth_code=") > -1) {
                src = src.split("?auth_code=")[1]
            }
            if (src.indexOf("&expires_in=") > -1) {
                src = src.split("&expires_in=")[0]
            }
            // 用授权码,请求获取授权信息
            postCreaterHttp('/merchant/addMerchantWarrantInfo', {authCode: src}, function (res) {
                if (res.errorCode == '200') {
                    $("#wait").html("配置成功!")
                } else if (res.errorCode == '100') {
                    $("#wait").html("账号已经授权!")
                } else {
                    $("#wait").html("配置失败!请重新授权")
                }
                $(".icon-success,.link").show();
                setInterval(function () {
                    num = num - 1
                    $(".link span").html(num)
                    if (num < 1) {
                        window.location.href = "https://www.xxx.com/xxx/pages/index.html"
                    }
                }, 1000)
            })
        })
    

    后端实现

    package com.litte.controller.warrantmerchant;
    
    import com.litte.controller.warrant.WarrantController;
    import com.litte.entity.reception.TWarrantInfo;
    import com.litte.entity.reception.TWarrantMerchant;
    import com.litte.service.jurisdiction.UserService;
    import com.litte.service.warrantinfo.TWarrantInfoService;
    import com.litte.service.warrantmerchant.TWarrantMerchantService;
    import com.litte.util.WinxinUtil;
    import net.sf.json.JSONObject;
    import org.apache.commons.lang.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.io.IOException;
    import java.util.Map;
    
    /**
    * @Description: 授权商户信息相关
    * @Author:      Mr.Jkx
    * @UpdateDate:  2019/5/10 15:44
    */
    @Controller
    @RequestMapping("/merchant")
    public class TWarrantMerchantController {
        private static final Logger LOGGER = LoggerFactory.getLogger(WarrantController.class);
        //公众号第三方平台的appid
        private static final String APPID = "APPID ";
        // 授权码获取授权公众号小程序信息
        private static final String API_QUERY_AUTH = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token=componentAccessToken";
        // 获取授权商户信息
        private static final String API_GET_AUTHORIZER_INFO = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token=componentAccessToken";
    
        @Autowired
        TWarrantMerchantService TWarrantMerchantService;
        @Autowired
        TWarrantInfoService tWarrantInfoService;
        @Autowired
        UserService userService;
    
        @RequestMapping("/addMerchantWarrantInfo")
        @ResponseBody
        public Map<String, String> addMerchantWarrantInfo(TWarrantMerchant tWarrantMerchant) throws IOException {
            int i = 0;
            String auth_code = tWarrantMerchant.getAuthCode(); // 授权码
            LOGGER.info("==========第三方授权:扫码授权页面回调,授权码:{}", auth_code);
            // 从数据库获取“component_access_token”令牌
            TWarrantInfo tWarrantInfo = tWarrantInfoService.selectByPrimaryKey("053882ef3bed46c795bbd7da470e79cf");
            String component_access_token = tWarrantInfo.getComponentAccessToken();
    
            JSONObject json = new JSONObject();
            json.accumulate("component_appid", APPID);
            json.accumulate("authorization_code", auth_code);
            /**发送Https请求到微信*/
            String url = API_QUERY_AUTH.replace("componentAccessToken", component_access_token);
            JSONObject retStr = WinxinUtil.doPostStr(url, json.toString());
            LOGGER.info("==========第三方授权: 授权码获取授权公众号小程序{}", retStr);
    
            JSONObject retJSONObject = JSONObject.fromObject(retStr);
            /**在返回结果中获取pre_auth_code*/
            LOGGER.info("==========第三方授权:获取授权者信息:{}", retJSONObject);
            String authorization_info = retJSONObject.getString("authorization_info");// 授权方信息载体authorization_info
            JSONObject jsonObject = JSONObject.fromObject(authorization_info);
    
            String authorizer_appid = jsonObject.getString("authorizer_appid");// 授权方appid
            String authorizerAccessToken = jsonObject.getString("authorizer_access_token");// 授权方令牌(配置小程序服务器域名会用到,随着令牌刷新,此字段也会刷新)
    
            // 获取授权商户信息
            Map<String, String> resMap = getTWarrantMerchantInfo(authorizer_appid, tWarrantMerchant.getCreater(), authorizerAccessToken);
            if(StringUtils.equals("200", resMap.get("errorCode"))){
                // 修改授权状态
                i = userService.updateWarrantType(tWarrantMerchant.getCreater());
                if(i > 0){
                    resMap.put("errorCode", "200");
                }else{
                    resMap.put("errorCode", "400");
                }
            }
            return resMap;
        }
    
        /**
         * @Description: 获取授权商户信息
         * @Author: Mr.Jkx
         * @Date: 2019/5/6 18:57
         */
        private Map<String, String> getTWarrantMerchantInfo(String authorizer_appid, String creater, String authorizerAccessToken) throws IOException {
            // 从数据库获取“component_access_token”令牌
            TWarrantInfo tWarrantInfo = tWarrantInfoService.selectByPrimaryKey("053882ef3bed46c795bbd7da470e79cf");
            String component_access_token = tWarrantInfo.getComponentAccessToken();
    
            JSONObject json = new JSONObject();
            json.accumulate("component_appid", APPID);
            json.accumulate("authorizer_appid", authorizer_appid);
    
            /**发送Https请求到微信*/
            String url = API_GET_AUTHORIZER_INFO.replace("componentAccessToken", component_access_token);
            JSONObject retStr = WinxinUtil.doPostStr(url, json.toString());
            LOGGER.info("==========第三方授权: 获取授权商户信息{}", retStr);
    
            JSONObject retJSONObject = JSONObject.fromObject(retStr);
            /**在返回结果中获取pre_auth_code*/
            LOGGER.info("==========第三方授权:获取授权商户信息:{}", retJSONObject);
    
            //授权商户信息保存数据库
            Map<String, String> resMap = insertTWarrantMerchantInfo(retJSONObject, creater, authorizerAccessToken);
            return resMap;
        }
    
        /**
         * @Description: 授权商户信息保存数据库
         * @Author: Mr.Jkx
         * @Date: 2019/5/6 19:00
         */
        private Map<String, String> insertTWarrantMerchantInfo(JSONObject retJSONObject, String creater, String authorizerAccessToken) {
            Map<String, String> resMap = TWarrantMerchantService.insertTWarrantMerchant(retJSONObject, creater, authorizerAccessToken);
            return resMap;
        }
    }
    /**
         * @Description: 授权商户信息保存数据库
         * @Author: Mr.Jkx
         * @Date: 2019/5/6 19:00
         */
    @Override
        public Map<String, String> insertTWarrantMerchant(JSONObject retJSONObject, String creater, String authorizerAccessToken) {
            Map<String, String> resMap = new HashMap<>();
            int i= 0;
            TWarrantMerchant tWarrantMerchant = new TWarrantMerchant();
            // 有效期
            long currentTime = new Date().getTime() + 120 * 60 * 1000;
            Date date = new Date(currentTime);
    
            String authorizerInfo = retJSONObject.getString("authorizer_info");// 授权方公众号小程序具体信息载体authorization_info
            JSONObject jsonObject = JSONObject.fromObject(authorizerInfo);
    
            String authorizationInfo = retJSONObject.getString("authorization_info");// 授权方公众号小程序授权信息载体authorization_info
            JSONObject jsonObject1 = JSONObject.fromObject(authorizationInfo);
    
            String serviceTypeInfo = jsonObject.getString("service_type_info");
            JSONObject jsonObject2 = JSONObject.fromObject(serviceTypeInfo);
    
            String verifyTypeInfo = jsonObject.getString("verify_type_info"); // 授权方认证类型,-1代表未认证,0代表微信认证
            JSONObject jsonObject3 = JSONObject.fromObject(verifyTypeInfo);
    
            // 授权方APPID
            String authorizerAppid = jsonObject1.getString("authorizer_appid");
    
            tWarrantMerchant.setId(UUIDUtil.getUUID());
            tWarrantMerchant.setAuthorizationAppid(authorizerAppid);
            tWarrantMerchant.setAuthorizerRefreshToken(jsonObject1.getString("authorizer_refresh_token"));
            tWarrantMerchant.setNickName(jsonObject.getString("nick_name"));
            tWarrantMerchant.setHeadImg(jsonObject.getString("head_img"));
            tWarrantMerchant.setServiceTypeInfo(jsonObject2.getString("id"));
            tWarrantMerchant.setVerifyTypeInfo(jsonObject3.getString("id"));
            tWarrantMerchant.setUserName(jsonObject.getString("user_name"));
            tWarrantMerchant.setPrincipalName(jsonObject.getString("principal_name"));
            tWarrantMerchant.setAlias(jsonObject.getString("alias"));
    //        tWarrantMerchant.setBusinessInfo(jsonObject.getString("business_info"));
            tWarrantMerchant.setQrcodeUrl(jsonObject.getString("qrcode_url"));
    //        tWarrantMerchant.setAuthorizationInfo(jsonObject.getString("authorization_info"));
    //        tWarrantMerchant.setFuncInfo(jsonObject.getString("func_info"));
    //        tWarrantMerchant.setMiniprograminfo(jsonObject.getString("miniprograminfo"));
            tWarrantMerchant.setCreateTime(DateUtil.formatDate(new Date(),"yyyy-MM-dd HH:mm:ss"));
            tWarrantMerchant.setDeadline(date);
            tWarrantMerchant.setCreater(creater);
            tWarrantMerchant.setAuthorizerAccessToken(authorizerAccessToken);
    
            // 根据授权方APPID查询此商户是否授权
    //        TWarrantMerchant tWarrantMerchant1 = new TWarrantMerchant();
    //        tWarrantMerchant1.setCreater(creater);
    //        TWarrantMerchant tWarrantMerchantData1 = tWarrantMerchantMapper.selWarrantMerchant(tWarrantMerchant1);
    //        if(null != tWarrantMerchantData1 && StringUtils.equals("1", tWarrantMerchantData1.getWarrantType())){
    //            resMap.put("errorCode", "100");
    //            return resMap;
    //        }else{
                TWarrantMerchant tWarrantMerchant2 = new TWarrantMerchant();
                tWarrantMerchant2.setAuthorizationAppid(authorizerAppid);
                TWarrantMerchant tWarrantMerchantData2 = tWarrantMerchantMapper.selWarrantMerchant(tWarrantMerchant2);
                if(null != tWarrantMerchantData2){
                    tWarrantMerchant.setId(tWarrantMerchantData2.getId());
                    i = tWarrantMerchantMapper.updateByPrimaryKeySelective(tWarrantMerchant);
                }else{
                    i = tWarrantMerchantMapper.insertSelective(tWarrantMerchant);
                }
                if(i>0){
                    resMap.put("errorCode", "200");
                    LOGGER.info("=======第三方授权:授权商户信息入库完毕!!!");
                    return resMap;
                }else{
                    resMap.put("errorCode", "300");
                    LOGGER.info("=======第三方授权:授权商户信息入库失败!!!");
                    return resMap;
                }
    //        }
        }
    
    展开全文
  • 微信开放平台“开发资源”中网站... 据开发者资质认证处介绍:开发者资质认证通过后,微信开放平台帐号下的应用,将获得微信登录、智能接口、第三方平台开发等高级能力。 所以在微信第三方授权登陆获取用户信息...
  • 1 微信开放平台:https://open.weixin.qq.com/ 2 微信官方教程:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=&...
  • 微信开放平台 和 微信公众平台 概念不同。   1、首先需要注册微信开放平台,然后获取开发者认证。审批通过之后再创建一个移动应用同样还是需要审批。通过之后就可以给这个应用添加微信授权登陆以及相应功能了...
  • http://www.cnblogs.com/linjunjie/p/6249989.html 微信开放平台 和 微信公众平台 概念不同。 第一步:获取AppID AppSecret(不做解释,自己去微信公众平台申请)   第二步:生成扫描二维码,获取code ...
  • 微信第三方开放平台研发实战

    万次阅读 2019-07-05 10:16:32
    微信开放平台之第三方平台是为了让公众号或小程序运营者,在面向垂直行业需求时,可以一键授权给第三方平台,让其帮助完成业务开发,且是基于微信 CRM 的必要组成模块之一。 对于刚开始接触第三方平台开发的人员来说...
  • 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。 授权流程说明 微信OAuth2.0授权...
  • 什么是微信公众平台、微信开放平台?它们之间又有什么区别?下面为大家详细介绍下!   开放平台是网站或app使用的接口平台,利用开放平台可在自己的网站或app上开发微信帐户登录、微信分享等功能! 公众平台是...
  • 微信公众平台、微信开放平台的关系背景简介微信公众平台能干什么?微信开放平台(open平台)能干什么? 背景 做微信相关开发的时候,要登录很多账号,而且不同的功能要在这两个账号之间切换来切换去,很烦;所以今天...
  • 最近在申请微信支付接口的时候遇到的坑爹问题,微信开放平台上也没什么说明,找了半天也没找到任何相关的文档,当然我创建的是IOS应用,所以可能这块资料比较少…… 回到正题,解决在微信开放平台创建IOS应用时应用...
  • 申请微信开放平台的主要目的:实现APP或者网站的微信登录。 所以要实现APP或者网站的微信登录,必须通过微信开放平台开发者资质认证(一年需要交纳300元)才能获得接口权限。 现在很多企业都已经实现了三证...
  • 如果你发现你其他操作没错,签名和微信开放平台的也一致,但是却报了微信应用签名与开放平台不一致的错误。 !!! 那你就要注意了:微信使用的应用签名必须是MD5,不能使用SHA1 ...
  • 微信开放平台 主要面对移动应用/网站应用开发者,为其提供微信登录、分享、支付等相关权限和服务。 微信开放平台还提供了数据统计功能,用于开发者统计接入应用的登录、分享等数据情况。 接入步骤 已京东APP举例...
  • 微信开放平台上创建移动应用

    千次阅读 2018-06-17 08:44:44
    本人因为想测试下微信第三方登陆和微信支付等功能,在微信开放平台上创建了一个移动应用(随便起了个名“呵什么呵”),但是由于暂时没有官网,填了www.baidu.com,作为官网,等了几天后发现审核未通过。我意识到可能...
  • 微信开放平台绑定各移动应用、网站应用、公众号、小程序、第三方的个数 目前没有在微信的文档中找到过具体的数字,只能真正的登录到后台,并且已经认证了的才能看的到。认证需要300元/年。 很多人都不知道具体的...
  • 背景:应用或多或少会接入微信分享的功能。但是由于某些原因,自己配置的应用信息与开放平台的信息一致,但还是会报错: “包名不对,请检查包名是否与开放...微信:签名不对,请检查签名是否与开放平台填写的一致...
1 2 3 4 5 ... 20
收藏数 73,733
精华内容 29,493
关键字:

微信开放平台