2016-11-15 11:38:46 qq_24091555 阅读数 20068
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

           由于项目需要,需要接触微信开发,并要调用微信的JS-SDK里面的接口。

       因为经验缺乏,我百度一下关于微信开发的资料,但收集的资料都不尽人意。网上的主流的微信开发是采用PHP开发的,而本人学的Java。所以对PHP微信开发只能看懂思路。更有的是,网上一些微信开发视频,也是和PHP有关的,关于用Java开发的甚少。

       无奈之下,我只好苦啃微信开发文档。大家都知道,微信官方给的开发文档真的有点那个啥,一个功能实现非要分几个地方来说,看完这块,又得点击另一个页面看完另一块,甚是麻烦。这样的设定也让我走了好多坑。

但功夫不负有心,在研究透了微信开发文档之后,我顺利在在项目中完成微信开发。现在我将微信开发的经验分享一下,希望对大家有所帮助。

       微信JS-SDK是微信公众号平台面向网页开发这提供基于微信内的网页开发工具包。接口大类分为:基础接口、分享接口、图像接口、音频接口、智能接口、设备信息、地址位置、摇一摇周边、界面操作、微信扫一扫、微信小店、微信卡劵和微信支付。一般使用频率高的就是分享接口、地理微信、微信扫一扫和微信支付。

接下来,我将主要讲解如何调用微信分享接口。

第一步,准备内网映射工具,ngrok。不清楚这个的同学可以去百度一下。https://ngrok.com为ngrok官网。要进行微信开发,内网映射工具是不可少。毕竟,我们程序员进行开发,要测试开发的产品是否能用,都先在自己的电脑跑一下。但由于ngrok的服务器在外国的,鉴于天朝的墙太高,访问可能不稳定。所以我推荐的是国内的natapp,免费和收费的都有,服务毕竟稳定可靠,只不过要想自定义二级域名就得交费成为VIP咯。

第二步,配置JS接口安全域名。登录要进行开发的公众号,点击公众设置--->功能设置。设置JS接口安全域名,要注意三点:①填写域名前面不需加上http://,例如你的域名是http://test.com,直接填写test.com即可;②域名默认80端口,只支持80和443端口,所以域名后面不能添加端口号。③该域名为你调用微信JS-SDK接口域名。

第三步,引用JS文件。在需要调用JS接口的页面引入http://res.wx.qq.com/open/js/jweixin-1.0.0.js 。


第四步,通过config接口注入权限验证配置 。具体参数有什么用处,在截图都有注释讲解。其中jsApiList为我们要使用的接口,我在下面共引用了五个接口,分别为微信好友分享、QQ好友分享、腾讯微博分享、QQ空间分享和朋友圈分享。调用的都是分享的接口。至于其他接口列表,可以去微信开发文档那浏览一下。这里就不详说。

        第五步,在服务器生成相关参数传到调用JS-SDK页面,完成授权。这是最重要的一步。如上图所示,appId,timestamp,nonceStr,signature都为必填参数。下面我将会详细说说如何生成这些参数并传回页面。

appId为开发的微信公众号的AppID(应用ID),我们可以在登录微信公众号,在开发选项中点击基本配置来查看。

timestamp为系统生成的时间戳。


nonceStr为服务器随机生成的字符串。



signature为微信JS-SDK使用权限算法。在生成signature之前,我们要拿到jsapi_ticket。官方文档是这样解释的:


我们要注意三个地方。jsapi_ticket要缓存两个小时,每过两个小时,向微信那边请求一次。获取jsapi_ticket要通过access_token。那么我们该如何获取access_token呢?


从文档可以看出,access_token需要AppID和AppSercet两个参数。而且access_token和jsapi_ticket一样,有效期皆为两小时。这就要求我们服务器要缓存access_token和jsapi_ticket,当有效期一过,就重新请求。有的人采用是用数据库来存取这两个参数,而我采用的是用Quartz定时器。关于Quartz定时器的使用,可浏览我上篇博客《SSH与Quartz集成》,里面有关于Quartz的使用方法。

AppSercet可在与APPID同一页面获取。接下来,调用接口,获取access_token。



接下来,我们用access_token去获取jsapi_ticket。


获取jsapi_ticket,就可以进行生成签名。在此之前,先看一下官方文档的签名算法。



用代码实现。


第六步,传生成的参数给网页。



第七步,调用已授权的JS接口。


第八步,利用微信Web开发者工具调试,看看是否授权成功。(微信web开发者工具可在微信开发下载)。



2017-04-26 11:45:11 gzhorizon0825 阅读数 785
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

工作中遇到开发微信第三方服务的需求,学习的同时记录一下开发的过程,给大家提供一个参考,希望能有些帮助,让大家少走些弯路。

首先说下开发流程,微信公众平台提供了大量的第三方接口供开发者调用,可以丰富微信公众号和服务号的功能,一遍提供更便捷的服务和完成复杂的业务流程,接入微信第三方平台有严格的要求,可以查看开发者文档:
公众平台开发者文档

首先需申请接口测试号,方便开发者测试接口功能:
这里写图片描述

用自己的微信号登录一下就行了。
登录成功后有测试号的信息,测试号的接口调用权限和微信认证服务号是一样的。
这里写图片描述

appID、appsecret是系统生成的测试应用号,正式上线时有微信分配的信息,URL和Token需开发者自己配置,URL为开发者开发的服务程序的资源,这里是认证action的映射,真是环境必须使用域名,这里我申请的花生壳内网穿透,审核服务费6元,懒得申请的可以百度下载一个ngrok,也是内网穿透工具。

要使微信服务号与我们开发的平台对接,需要先进行有效性验证,具体实现过程如下。

Java方面用的是SpringMVC,首先配置文件中添加基本信息:
这里写图片描述

按自己的测试号信息配置。

第二步,增加SpringMVC映射:

@Controller
@RequestMapping("/")
public class WXVerifyController {

    private static final Logger log = Logger.getLogger(WXVerifyController.class);
    @RequestMapping("api")
    public @ResponseBody String wxVerify(HttpServletRequest request){
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        //正式微信公众号
        String token = ConstantUtil.getPropertiesValue("system", "Token");
        try
        {
            // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
            if (SignUtil.checkSignature(token,signature, timestamp, nonce)) {
                log.warn(echostr);
                return echostr;
            }
        }catch(Exception ex)
        {
            return "Illegal Call";
        }
        return "ERROR";
    }


}

ConstantUtil.getPropertiesValue();方法是读取配置文件的方法。

public class SignUtil {

    /**
     * 19      * 验证签名
     * 20      *
     * 21      * @param signature
     * 22      * @param timestamp
     * 23      * @param nonce
     * 24      * @return
     * 25
     */
    public static boolean checkSignature(String token,String signature, String timestamp,
                                         String nonce) {
        String[] arr = new String[]{token, timestamp, nonce};
        // 将token、timestamp、nonce三个参数进行字典序排序
        //Arrays.sort(arr);
        sort(arr);
        StringBuilder content = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }
        MessageDigest md;
        String tmpStr = null;

        try {
            md = MessageDigest.getInstance("SHA-1");
            // 将三个参数字符串拼接成一个字符串进行sha1加密
            byte[] digest = md.digest(content.toString().getBytes());
            tmpStr = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        content = null;
        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }

    /**
     * 54      * 将字节数组转换为十六进制字符串
     * 55      *
     * 56      * @param byteArray
     * 57      * @return
     * 58
     */
    private static String byteToStr(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byteToHexStr(byteArray[i]);
        }
        return strDigest;
    }

    /**
     * 68      * 将字节转换为十六进制字符串
     * 69      *
     * 70      * @param mByte
     * 71      * @return
     * 72
     */
    private static String byteToHexStr(byte mByte) {
        char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
                'B', 'C', 'D', 'E', 'F'};
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }

    public static void sort(String a[]) {
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = i + 1; j < a.length; j++) {
                if (a[j].compareTo(a[i]) < 0) {
                    String temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
    }
}

到这里Token验证基本完成了,打开内网穿透,填写服务器URL,在测试号管理界面完成验证。

2018-08-24 14:33:38 qq_34190023 阅读数 5470
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

 

微信开放平台开发系列文章:

微信开放平台开发第三方授权登陆(一):开发前期准备

微信开放平台开发第三方授权登陆(二):PC网页端

微信开放平台开发第三方授权登陆(三):Android客户端

微信开放平台开发第三方授权登陆(四):微信公众号

微信开放平台开发第三方授权登陆(五):微信小程序

 

 

目录

一、需求

二、开发流程

三、具体实现步骤

1.引导用户跳转到微信授权网页

2. 通过code换取网页授权access_token

3.根据token获取用户信息

四、参数位置:


一、需求

根据需求,需要拥有第三方微信登录功能,并获取到用户信息。

二、开发流程

微信公众平台第三方授权登录的应用场景在于 : 在微信客户端(PC或APP)访问第三方网页,公众号可以通过网页授权机制,获取用户基本信息,实现业务逻辑。

1用户同意授权,获取code

2通过code换取网页授权access_token

3通过access_token拉取用户信息(需scope为 snsapi_userinfo)

公众号第三方授权获取用户信息基本流程

三、具体实现步骤

1.引导用户跳转到微信授权网页

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

参数

说明

appid

公众号的唯一标识

redirect_uri

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

response_type

返回类型,请填写code

scope

应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 )

state

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

#wechat_redirect

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

如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。

注意:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期

 @RequestMapping("/login")
    public String wechatLogin(HttpServletRequest httpServletRequest) {

        // 应用授权作用域:
        // 当为snsapi_base时,不弹出授权页面,直接跳转,只能获取用户openid。
        // 当为snsapi_userinfo时,弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息
        String scope = "snsapi_userinfo";

        String state = UUID.randomUUID().toString().replaceAll("-","");

        // 采用redis等进行缓存state 使用sessionId为key 30分钟后过期,可配置
        RedisPoolUtil.setEx("wechat-mp-state-"+httpServletRequest.getSession().getId(), state, Integer.parseInt(env.getProperty("wechat.mp.exTime", "1800")));

        log.info("state= "+state);

        // 微信公众平台
        String get_auth_url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
                + "appid="
                + env.getProperty("wechat.mp.appid")
                + "&redirect_uri="
                + env.getProperty("application.url")
                + env.getProperty("wechat.mp.redirect_uri")
                + "&response_type=code"
                + "&scope="
                + scope
                + "&state="
                + state
                + "#wechat_redirect";

        log.info("URL:"+get_auth_url);

        return "redirect:" + get_auth_url;
    }

2. 通过code换取网页授权access_token

用户同意授权后,通过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", //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同

"expires_in":7200,  // access_token接口调用凭证超时时间,单位(秒)

"refresh_token":"REFRESH_TOKEN", //用户刷新access_token

"openid":"OPENID",  //用户唯一标识

"scope":"SCOPE" }   //用户授权的作用域,使用逗号(,)分隔

错误返回样例:

{"errcode":40029,"errmsg":"invalid code"}


 

@RequestMapping("/getInfo")
    public String getInfo(HttpServletRequest httpServletRequest, Model model) {

        String code = httpServletRequest.getParameter("code");
        String state = httpServletRequest.getParameter("state");

        String value = RedisPoolUtil.get("wechat-mp-state-"+httpServletRequest.getSession().getId());

        log.info("Code = " + code+"  . State="+state+"    value="+value);

        /* 如果state值不匹配,则为非法请求,抛出异常 */
        if (StringUtils.isEmpty(code)||StringUtils.isEmpty(state)||value==null || !state.equals(value)){
            throw new RuntimeException("非法请求");
        }

        // 通过code换取网页授权access_token
        String get_access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" +
                env.getProperty("wechat.mp.appid") +
                "&secret=" +
                env.getProperty("wechat.mp.secret") +
                "&code=" +
                code +
                "&grant_type=authorization_code";

        log.info(get_access_token_url);


        JSONObject accessTokenJsonObject = HttpClientUtils.httpGet(get_access_token_url);

        checkResult(accessTokenJsonObject);
        // 成功获取
        String access_token = (String) accessTokenJsonObject.get("access_token");
        Integer expires_in = (Integer) accessTokenJsonObject.get("expires_in");//access_token接口调用凭证超时时间,单位(秒)
        String userOpenid = (String) accessTokenJsonObject.get("openid");//用户唯一标识
        String scope = (String) accessTokenJsonObject.get("scope");//用户授权的作用域,使用逗号(,)分隔

        // TODO:文档没有写返回unionid,需要在实际公众号中进行测试(绑定开放平台的会有),如果没有unionid,则用openid存储用户,虽然这并不是合理的做法。因为openid仅仅该公众号下的用户唯一标识。。。

//        access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,
//        refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权

        WeChatUserInfo weChatUserInfo = null;

        weChatUserInfo = null; //FIXME: 根据unionid从数据库中查询
        if (weChatUserInfo == null){
            weChatUserInfo = getMPWeChatUserInfo(access_token,userOpenid);
            // insert into database

        }

        if (weChatUserInfo.getUnionid()!=null){
            // 当前是绑定开放平台的公众号.Union将成为唯一标识

        }

        model.addAttribute(weChatUserInfo);
        return "wechatUser";
    }

3.根据token获取用户信息

http:GET(请使用https协议) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

参数

描述

access_token

网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同

openid

用户的唯一标识

lang

返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语

正确时返回的JSON数据包如下:

{

"openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

private WeChatUserInfo getMPWeChatUserInfo(String accessToken, String openId){

        String get_userInfo_url = "https://api.weixin.qq.com/sns/userinfo?" +
                "access_token=" +
                accessToken +
                "&openid=" +
                openId +
                "&lang=zh_CN";

        JSONObject userInfoJsonObject = HttpClientUtils.httpGet(get_userInfo_url);

        checkResult(userInfoJsonObject);

        String user_openid = (String) userInfoJsonObject.get("openid");
        String user_nickname = (String) userInfoJsonObject.get("nickname");
        Integer user_sex = (Integer) userInfoJsonObject.get("sex");//用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
        String user_province = (String) userInfoJsonObject.get("province");
        String user_city = (String) userInfoJsonObject.get("city");
        String user_country = (String) userInfoJsonObject.get("country");//国家,如中国为CN,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
        String user_headimgurl = (String) userInfoJsonObject.get("headimgurl");//头像
        List user_privilege = (List) userInfoJsonObject.get("privilege");//用户特权信息,json 数组,如微信沃卡用户为(chinaunicom)
        String user_unionid = (String) userInfoJsonObject.get("unionid");


        WeChatUserInfo weChatUserInfo = new WeChatUserInfo();
        weChatUserInfo.setOpenid(user_openid);
        weChatUserInfo.setNickname(user_nickname);
        weChatUserInfo.setSex(user_sex);
        weChatUserInfo.setProvince(user_province);
        weChatUserInfo.setCity(user_city);
        weChatUserInfo.setCountry(user_country);
        weChatUserInfo.setHeadimgurl(user_headimgurl);
        weChatUserInfo.setPrivilege(StringTools.listToString(user_privilege));
        weChatUserInfo.setUnionid(user_unionid);

        log.info("用户信息如下:" +
                "   opeinId:" + user_openid +
                "   用户昵称:" + user_nickname +
                "   用户的性别:" + user_sex +
                "   省份:" + user_province +
                "   城市:" + user_city +
                "   国家:" + user_country +
                "   头像:" + user_headimgurl +
                "   用户特权信息:" + user_privilege +
                "   UnionId:" + user_unionid
        );

        return weChatUserInfo;
    }

四、参数位置:

开放平台绑定公众号:

2018-09-03 17:12:38 qq_34190023 阅读数 15869
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

 微信开放平台开发系列文章:

微信开放平台开发第三方授权登陆(一):开发前期准备

微信开放平台开发第三方授权登陆(二):PC网页端

微信开放平台开发第三方授权登陆(三):Android客户端

微信开放平台开发第三方授权登陆(四):微信公众号

微信开放平台开发第三方授权登陆(五):微信小程序

 

目录

一、需求

二、开发流程

三、开发使用的技术及工具

1.前端(小程序)

1)自定义的全局变量

2)index加载时进行登录

3)授权页面authorization.wxml

4)用户信息发送给后端

5)用户详情页mine.wxml

2.服务端(Java)

1).配置文件新增小程序相关配置

2)获取openid以及Sessionkey

3).获取用户信息:


 

开发小程序需要在公众平台注册一个小程序账号,然后获取到小程序的AppID和AppSecret。就可以进行第三方登陆授权开发。

一、需求

拥有第三方微信登录功能,并获取到用户信息。

二、开发流程

小程序:

1. 微信小程序通过wx.login API进行登录获取code。由于AppID和AppSecret不能泄露给用户,根据code获取openid需要在服务端完成,所以需要将code发送给服务端

(服务端),并且带上授权临时票据code参数;

2. 服务端通过code和appid、APPSecret获取到openid和SessionKey。服务端需要返回自定义登录态给前端,不能返回SessionKey

3. 前端保存自定义登录态,获取用户信息时携带自定义登录态给后端。

获取Token的流程

三、开发使用的技术及工具

1、.后端采用IDEA2017 进行开发

2、前端使用微信开发者工具V1.02进行开发

3、使用fastJson对json数据进行处理

四、具体实现步骤

1.前端(小程序)

目录结构如下:

1)自定义的全局变量

globalData: {

    userInfo: null,

    sessionkey:null

  }

自定义userInfo用于存储用户信息

sessionKey用于存储服务端发回给客户端的sessionkey

2)index加载时进行登录

用户登录后,服务端会返回一个sessionkey给客户端保存,如果为空,说明没有登录过,需要调用wx.login进行登录。

调用wx.login后,微信会返回一个code给小程序,小程序需要通过这个code发送给自身的服务端来获取sessionkey和openid信息。

onLoad: function() {

    var serverUrl = app.serverUrl;

    // 加载时,检查当前用户信息是否登录

    if (app.globalData.sessionkey != null) { // 已经登录了

      // 是否授权

      wx.getSetting({

        success: function(res) {

          if (res.authSetting['scope.userInfo']) {

            // 已经授权,可以直接调用 getUserInfo 获取头像昵称

            wx.getUserInfo({

              success: function(res) {

                app.globalData.userInfo = JSON.parse(res.rawData);

              }

            })

          } else {

            // 还没有授权,则需要授权

            wx.redirectTo({

              url: '../authorization/authorization'

            })

          }

        }

      })

    } else { // 还没有登录

      // 提示用户登录授权

      wx.login({

        success: res => {

          // 发送 res.code 到后台换取 openId, sessionKey, unionId

          if (res.code) {

            // 发送请求,服务端能获取到openid和unionid,之前登录过则可以获取到之前的用户信息。

            wx.request({

              url: serverUrl + '/miniprogram/login/' + res.code, //请求路径

              method: "GET",

              success: function(res) {

                app.globalData.sessionkey = res.data;

                // 进入授权

                wx.redirectTo({

                  url: '../authorization/authorization'

                })

              }

            })

          }

        }

      })

    }

},

登录成功后,重定向到授权页面

3)授权页面authorization.wxml

<view class='tag-title'>

  <image mode="widthFix" style=' width: 200rpx;height: 200rpx;margin-top:150rpx' src="/images/logo.jpg"></image>

</view>

<view wx:if="{{canIUse}}">

  <view style='text-align:center;margin-top:50rpx'>

    允许微信授权后,可体验更多功能</view>

  <view>

    <button open-type='getUserInfo' bindgetuserinfo="bindGetUserInfo" >授权登录</button>

    <button bindtap='navigateBack'>返回首页</button>

  </view>

</view>

<view wx:else style='text-align:center;margin-top:50rpx'>

  您的微信版本过低,请升级后再次体验</view>

Button的open-type为getUserInfo时,点击后会调用bindgetuserinfo属性配置的函数,同时带上用户基本信息(不包括Openid等)

4)用户信息发送给后端

// 授权登录按钮

  bindGetUserInfo: function(e) {

    let that = this;

    var serverUrl = app.serverUrl;

    console.log(e.detail.userInfo)

    if (e.detail.userInfo) {  // 成功获取到信息

      app.globalData.userInfo = e.detail.userInfo

      // 这里可以将用户信息发送给后台

      // 获取到sessionkey

      if (app.globalData.sessionkey!=null){

        wx.request({

          url: serverUrl + '/miniprogram/userinfo', //请求路径,

          method: "GET",

          data: {

            // openid: this.openid,

            // unionid: this.unionid,

            key: app.globalData.sessionkey,

            nickname: app.globalData.userInfo.nickName, //获取昵称

            gender: app.globalData.userInfo.gender, //获取性别

            province: app.globalData.userInfo.province, //获取省份

            city: app.globalData.userInfo.city, //获取城市

            country: app.globalData.userInfo.country, //获取国家

            avatarUrl: app.globalData.userInfo.avatarUrl, //这些是用户的基本信息

            language: app.globalData.userInfo.language

          },

          success: function (res) {

            if (res.data.code == 0) {  // 请求成功

              debugger

              app.globalData.userInfo = res.data.data; // 以数据库中返回的数据为准

              // 获取用户信息成功

              wx.switchTab({

                url: '../mine/mine'

              })

            }

          }

        })

      }else{

        this.showZanTopTips('错误:SessionKey为null');

      }



    } else {

      this.showZanTopTips('您拒绝了微信授权');

    }

  },



}));

获取用户信息成功后,页面跳转到mine中显示用户详情信息

5)用户详情页mine.wxml

<view class="container more">

  <view class="userinfo">

    <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>

    <text class="userinfo-nickname">{{userInfo.nickName}}</text>

          <text class="userinfo-nickname">性别:{{userInfo.gender === 1 ? '男':'女'}}</text>

          <text class="userinfo-nickname">城市:{{userInfo.city}}</text>

          <text class="userinfo-nickname">省份:{{userInfo.province}}</text>

          <text class="userinfo-nickname">国家:{{userInfo.country}}</text>

          <text class="userinfo-nickname">使用语言:{{userInfo.language}}</text>

  </view>

</view>

2.服务端(Java)

服务端需要做的是:接受小程序前端发送的请求,根据发送过来的code,以及服务端保存的AppId和APPSecret等向微信服务端发送请求,获取到sessionkey和openid,然后将二者关联起来保存到session存储器中(Redis),返回给前端key值。

接受小程序发送过来的key和用户基本信息,根据key从redis中获取openid,然后对数据库进行查询,若存在数据则封装后返回给前端,若无信息则向数据库中插入数据并返回给前端。

1).配置文件新增小程序相关配置

wechat.miniprogram.appid =

wechat.miniprogram.appsecret =

2)获取openid以及Sessionkey

@ResponseBody

    @RequestMapping("/login/{code}")

    public String login(@PathVariable("code") String code) {

        String url = "https://api.weixin.qq.com/sns/jscode2session?" +

                "appid=" +

                env.getProperty("wechat.miniprogram.appid") +

                "&secret=" +

                env.getProperty("wechat.miniprogram.appsecret") +

                "&js_code=" +

                code +

                "&grant_type=authorization_code";

        JSONObject object = HttpClientUtils.httpGet(url);

        // 请求,获取openid或unionid

        // 从数据库中查询是否存储

        // 成功获取

        String unionid = (String) object.get("unionid");

        String openid = (String) object.get("openid");//用户唯一标识

        // 会话密钥session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。

        String session_key = (String) object.get("session_key");

        String key = "wechatminiprogramkey-" + UUID.randomUUID().toString().replaceAll("-", "");

        RedisPoolUtil.setEx(key, openid + "---" + session_key, 9600);

        return key;

}

3).获取用户信息:

小程序能够获取用户基本信息,但是不包括openid等信息,仅有基本的昵称等信息,需要通过后端传输的key作为标识发送到前端,然后找到对应的openid来获取。

@ResponseBody

@RequestMapping(value = "/userinfo", method = RequestMethod.GET) // 获取用户信息

public Result getOpenId(String key, MiniProgramBaseUserInfo miniProgramBaseUserInfo) {

        MiniProgramBaseUserInfo result = null;

        String value = RedisPoolUtil.get(key);

        if (value != null) {

            String values[] = value.split("---");

            String openid = values[0];

            // 从数据库中查询是否存储(根据openid查询)

            result = null; // TODO: 这里是查数据库操作

            if (result == null){ // 数据库中没有数据

                // TODO: 向数据库中执行插入操作

                // insert  weChatUserInfo

                result = miniProgramBaseUserInfo;

            }

            return Result.success(result);

        return Result.error(SESSION_KEY_OVER_TIME); // SessionKey失效

    }

 

2018-12-09 14:39:38 Eggbeauty 阅读数 846
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27842 人正在学习 去看看 秦子恒

当我们希望在微信小程序中调用第三方API时,首先要做的是将该域名加入至合法域名中,方可正常使用API。具体操作如下:

登入微信公众平台,找到“设置-开发设置-服务器域名“,点击右侧的“修改”按钮即可添加合法域名
微信公众平台-设置-开发设置-服务器域名

添加完成后,若在“微信开发者工具”的“设置-项目设置-域名信息“中能找到新添加的域名,则表示该API可正常调用。

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