微信小程序-获取OPENID做为用户的唯一标识

需求-获取openId做为用户的唯一标识

以下内容基于UNI-APP+SPRINGBOOT

1 分析需求

获取openId需要调用调用 auth.code2Session接口(GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),该接口需要3+1个参数,这里的3是:appid+secret+js_code。

3个参数的获取方法

  1. js_code需要通过调用 wx.login() 获取临时登录凭证code ,而小程序插件中使用时,需要在用户信息功能页中获得用户授权之后调用。否则将返回 fail, 这时候如果打印wx.login的返回值res,那么code是“the code is a mock one”。因此,我们还需要先获得授权,然后使用wx.login获得code
  2. 可以通过下述步骤找到appid,secret

微信公众平台 > > > 左侧菜单栏- - -开发- - -开发管理 > > > 开发设置

在这里插入图片描述

请求参数和返回值详见官网:HTTPS://DEVELOPERS.WEIXIN.QQ.COM/MINIPROGRAM/DEV/API-BACKEND/OPEN-API/LOGIN/AUTH.CODE2SESSION.HTML

为优化用户体验,使用 WX.GETUSERINFO 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版调用 WX.GETUSERINFO 接口,将无法弹出授权询问框,默认调用失败。正式版暂不受影响。开发者可使用以下方式获取或展示用户信息

2 解决思路

  1. 获得授权
  2. 通过WX.LOGIN()获得CODE
  3. 在微信开发平台获取APPID,SECRET
  4. 调用AUTH.CODE2SESSION(GET HTTPS://API.WEIXIN.QQ.COM/SNS/JSCODE2SESSION?APPID=APPID&SECRET=SECRET&JS_CODE=JSCODE&GRANT_TYPE=AUTHORIZATION_CODE)接口获得OPENID,

3 获得授权

调用WX.GETUSERPROFILE可弹出确认授权框,建议事件驱动

代码示例如下:

getUserInfo:function(){
    wx.getUserProfile({
        desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
        success: (res) => {
            console.log(res);
            console.log(res.userInfo);
            // 获取code
            this.getCode();
        },
        fail: (res)=>{
            console.log(res)
        }

    })
},

4 获得code

getCode(){
    let _this = this;
    wx.login({
        success (res) {
            console.log(res);
            let code=res.code;
            if (code) {
                //发起网络请求,_this.request是我基于wx.request做的封装,后附着代码
                _this.request({
                    // url 自己的服务器或者后端的请求路径
                    url: 'http://localhost:8010/weixin/login',
                    data: {code:code}
                }).then(res => {
                    console.log(res);
                })
            } else {
                console.log('登录失败!' + res.errMsg)
            }
        }
    })
}

这里我是封装的WX.REQUEST,路径SRC/UTILS/REQUEST.JS,

export default (params) => {
    return new Promise((resolve, reject) => {

        // 加载中
        uni.showLoading({
            title: "加载中"
        })

        wx.request({
            ...params,
            success(res) {
                resolve(res.data);
            },
            fail(err) {
                reject(err);
            },
            complete() {
                uni.hideLoading();
            }
        })
    })
}

在MAIN.JS中全局引入REQUEST,

import request from "./utils/request";
Vue.prototype.request = request;

5 后端接收code,返回openId

后端通过CODE向HTTPS://API.WEIXIN.QQ.COM/SNS/JSCODE2SESSION?APPID=APPID&SECRET=SECRET&JS_CODE=JSCODE&GRANT_TYPE=AUTHORIZATION_CODE发送请求,获得OPENID,并返回

后端参考原文:https://blog.csdn.net/mengdi_cao/article/details/109717187

5.1 封装请求参数

@Getter
public class WeixinLoginParams {
    private String secret="b1d3de815c086fcc88f0fe06d4dc7da9";
    private String appid = "wx753dc3d18bcd580e";
    private final String grantType="authorization_code";
}

5.2 封装返回值

@Data
@ToString
public class WXloginRes {
    private String openid;
    private String sessionKey;
    private String errcode;
    private String errmsg;
}

5.3 封装工具类用于向接口发起请求

import com.alibaba.fastjson.JSONObject;
import com.restaurant.order.vo.WXloginRes;
import com.restaurant.order.vo.WeixinLoginParams;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;

public class WeiXinLoginUtils {

    public static WXloginRes getLoginResult(String code){

        RestTemplate restTemplate = new RestTemplate();
        WeixinLoginParams loginParams = new WeixinLoginParams();
        WXloginRes wXloginRes = new WXloginRes();

        // 封装请求参数
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type={grantType}";
        Map<String, String> requestMap = new HashMap<>();
        requestMap.put("appid", loginParams.getAppid());
        requestMap.put("secret", loginParams.getSecret());
        requestMap.put("grantType", loginParams.getGrantType());
        requestMap.put("code", code);

        // 发送请求,获得返回值
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class,requestMap);
        // 转换成json对象
        JSONObject jsonObject=JSONObject.parseObject(responseEntity.getBody());
        String openId=jsonObject.getString("openid");
        String sessionKey=jsonObject.getString("session_key");
        String errcode = jsonObject.getString("errcode");
        String errmsg = jsonObject.getString("errmsg");

        // 给返回对象wXloginRes赋值
        wXloginRes.setOpenid(openId);
        wXloginRes.setOpenid(sessionKey);
        wXloginRes.setErrcode(errcode);
        wXloginRes.setErrmsg(errmsg);

        return wXloginRes;
        
    }
}

5.4 书写接口

这里的Result是我自己封装的统一返回对象,详见:https://blog.csdn.net/qq_43644923/article/details/116507939?spm=1001.2014.3001.5501

@GetMapping("/login")
public Result login(String code){
    if (code==null){
        return Result.error("错误,请重新授权");
    }else {

        return Result.success(WeiXinLoginUtils.getLoginResult(code));
    }
}

d);
wXloginRes.setOpenid(sessionKey);
wXloginRes.setErrcode(errcode);
wXloginRes.setErrmsg(errmsg);

    return wXloginRes;
    
}

}




##### 4.5.4 书写接口

这里的Result是我自己封装的统一返回对象,详见:https://blog.csdn.net/qq_43644923/article/details/116507939?spm=1001.2014.3001.5501

```java
@GetMapping("/login")
public Result login(String code){
    if (code==null){
        return Result.error("错误,请重新授权");
    }else {

        return Result.success(WeiXinLoginUtils.getLoginResult(code));
    }
}
http://www.jnnr.cn/news_show_409.html

posted on 2021-05-08 15:40  爱编程的小伙子  阅读(1864)  评论(0编辑  收藏  举报