SpringCloud 微信小程序 获取用户信息一键登录 【SpringCloud系列15】

SpringCloud 大型系列课程正在制作中,欢迎大家关注与提意见。

本文章是系列文章中的一篇

本文章实现的是微信小程序获取微信用户信息授权登录。

在这里插入图片描述
实现微信小程序用户登录的方案有三种,本文章实现的是第三种。

方案一 只获取用户对应的openId,来创建标记用户
方案二 获取用户对应的openId与微信绑定的手机来,来创建标记用户
方案三 获取微信用户的基本信息,来创建标记用户。

1 微信小程序代码

我这里实现的页面只是一个登录按钮

<view style='width:100%;padding-left:30rpx;font-size: 30rpx;margin-top:20rpx;'>
  2. 同意当前小程序获取我的个人信息;
  <button type="primary" bindtap="getUserProfile">授权微信头像与昵称</button>
</view>

然后在对应的 页面js 中,当进入这个登录页面时,调用 wx.login 获取 code 核心代码如下

    let that = this;
    wx.login({
      success: function (loginRes) {
        that.setData({
          loginRes: loginRes
        });
      },
      fail: function (err) {
        wx.showModal({
          title: '提示',
          showCancel: false,
          content: '授权失败',
          success: function (res) {
            console.log(res)
            // 拒绝授权确定后到逻辑处理
            wx.navigateBack();
          }
        })
      }
    });

这里保存了临时的 loginRes ,这个 loginRes 中的 code 只能使用一次,所以在下面调用如果出现错误 就需要退出页面重新进入,重新获取

1.1 获取 微信用户信息

用户点击按钮,调用获取微信获取用户信息的接口 wx.getUserProfile

  // 获取用户昵称头像
  getUserProfile() {
    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
    // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: '用于展示个人中心头像,昵称', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        console.log(res);
        // 授权拿到昵称头像后处理的逻辑
        //业务代码处理
        this.requestAuthFunction(res);
      },
      fail: (err) => {
        console.log(err);
        wx.showModal({
          title: '提示',
          showCancel: false,
          content: '取消授权',
          success: function (res) {
            console.log(res)
            // 拒绝授权确定后到逻辑处理
          }
        })
      }
    });
  },
1.2 获取微信用户信息

微信授权通过后,就需要请求业务接口后台,来解密用户信息

  requestAuthFunction(infoRes) {
    wx.request({
      url: api.AuthLoginByWeixin,
      method: "post",
      header: {
        'appId': ''
      },
      data: {
        code: this.data.loginRes.code,
        rawData: infoRes.rawData, //用户非敏感信息
        signature: infoRes.signature, //签名
        encryptedData: infoRes.encryptedData, //用户敏感信息
        iv: infoRes.iv //解密算法的向量
      },
      success: function (res) {
        console.log('login success');
        console.log("res:", res)
        wx.setStorageSync('token', res.data.data.access_token);
        wx.setStorageSync('userInfo', res.data.data);
        console.log("token=" + res.data.data.access_token);
        wx.navigateBack();
      },
      fail: function (error) {
        //调用服务端登录接口失败
        console.log(error);
        wx.navigateBack();
      }
    });
  },

我这里请求 header 添加 了appId,是兼容支持多个小程序的配置,在业务后台处理里,需要根据 appId 来查询小程序的配置。

其实查询用户信息可以不使用 code ,我这里只是为了使用 code 来获取 openId 与 SessionKey .

2 业务后台代码

微信业务处理的功能在 wx-service 服务中,在《SpringCloud 微信小程序授权登录 获取openId SessionKey【SpringCloud系列13】》 中有概述

@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/wx")
public class WxUserController {


    @Autowired
    private WxAppLoginService wxAppLoginService;

    /**
     * 小程序用户登录
     *
     * @param request
     * @param loginDTO
     * @return
     */
    @ApiOperation(value = "小程序用户登录=code、用户的基本信息")
    @PostMapping("/login_by_userinfo")
    public Map<String,Object> loginMa(HttpServletRequest request, @RequestBody MiniLoginRequest loginDTO) throws WxErrorException {
        return wxAppLoginService.login(loginDTO);
    }
]

然后对应的实现类

@Service
@Slf4j
public class WxAppLoginServiceImpl implements WxAppLoginService {

    //查询数据库小程序配置
    @Autowired
    private WxAppInfoService wxAppInfoService;


    private WxMaService getWxMaService(String appId) {
        //查询数据库小程序的配置
        WxAppInfo wxAppInfo = wxAppInfoService.queryByAppId(appId);
        String appSecret = wxAppInfo.getSecret();

        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
        config.setAppid(appId);
        config.setSecret(appSecret);
        config.setMsgDataFormat("JSON");
        WxMaService wxMaService = new WxMaServiceImpl();
        wxMaService.setWxMaConfig(config);
        return wxMaService;
    }
    

    @Override
    public Map<String, Object> login(MiniLoginRequest request) throws WxErrorException {


        final WxMaService wxService = getWxMaService(request.getAppId());

        // 获取微信用户session
        WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(request.getCode());
        if (null == session) {
            throw new RuntimeException("login handler error");
        }
        String openid = session.getOpenid();
        String sessionKey = session.getSessionKey();
        String unionid = session.getUnionid();
        log.info("微信登录 openid {} unionid {} sessionKey {}", openid, unionid, sessionKey);


        String iv = request.getIv();
        String encryptedData = request.getEncryptedData();
        String rawData = request.getRawData();
        String signature = request.getSignature();

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {

        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);

        String nickName = userInfo.getNickName();
        String avatarUrl = userInfo.getAvatarUrl();
        String unionId = userInfo.getUnionId();

        Map<String, Object> map = new HashMap<>();
        map.put("openId", openid);
        map.put("unionId", unionId);
        map.put("sessionKey", sessionKey);
        map.put("code", 200);

        map.put("nickName", nickName);
        map.put("avatarUrl", avatarUrl);

        return map;

    }
}

本项目 SpringCloud 源码 https://gitee.com/android.long/spring-cloud-biglead/tree/master/biglead-api-11-admin
本项目 管理后台web 源码https://gitee.com/android.long/spring-cloud-biglead/tree/master/mall-admin-web-master
本项目 小程序 源码https://gitee.com/android.long/spring-cloud-biglead/tree/master/mall-app-web-master
如果有兴趣可以关注一下公众号 biglead ,每周都会有 java、Flutter、小程序、js 、英语相关的内容分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早起的年轻人

创作源于分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值