后台交互-个人中心->小程序登录微信登录接口演示,小程序授权登录理论,小程序授权登录代码演示,微信表情包存储问题

简介: 后台交互-个人中心->小程序登录微信登录接口演示,小程序授权登录理论,小程序授权登录代码演示,微信表情包存储问题
  • 小程序登录微信登录接口演示
  • 小程序授权登录理论
  • 小程序授权登录代码演示
  • 微信表情包存储问题

1.小程序登录微信登录接口演示

推荐使用 wx.getUserProfile 获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认

// pages/index/index.js
Page({
  data: {
    userInfo: {},
    canIUseGetUserProfile: false,
  },
  onLoad() {
    // if (wx.getUserProfile) {
    //   this.setData({
    //     canIUseGetUserProfile: true
    //   })
    // }
  },
  getUserProfile(e) {
    console.log('getUserProfile')
    // 推荐使用 wx.getUserProfile 获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认
    // 开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
    wx.getUserProfile({
      desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
      success: (res) => {
        console.log(res);
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true
        })
      }
    })
  },
  wxLogin: function(e) {
    debugger
    console.log('wxLogin')
    console.log(e.detail.userInfo);
    this.setData({
      userInfo: e.detail.userInfo
    })
    if (e.detail.userInfo == undefined) {
      app.globalData.hasLogin = false;
      util.showErrorToast('微信登录失败');
      return;
    }
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
  },
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
  },
  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
  },
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {
  },
  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {
  },
  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {
  },
  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {
  }
})
<!--pages/index/index.wxml-->
<view>
  <button wx:if="{{canIUseGetUserProfile}}" type="primary" class="wx-login-btn" bindtap="getUserProfile">微信直接登录1</button>
  <button wx:else open-type="getUserInfo" type="primary" class="wx-login-btn" bindgetuserinfo="wxLogin">微信直接登录2</button>
  <image mode="scaleToFill" src="{{userInfo.avatarUrl}}" />
  <text>昵称:{{userInfo.nickName}}</text>
</view>

2.小程序授权登录理论

小程序:小程序对应的项目,自己写的前端


临时的code,是一个临时的字符串


开发者服务器;小程序后台接口,自己写的后端


appid:是指小程序相对于微信软件的唯一标识


微信接口服务:微信的接口服务器,不是我们自己写的代码(看成阿里云的短信服务)


session_key:指的是当前的登录请求,指的是一次会话


openid:登录的用户(javaxl),相当于微信小程序这款软件的唯一标识


storage:看成vue中vuex


3.小程序授权登录代码演示

//oa-mini\utils\user.js
/**
 * 用户相关服务
 */
const util = require('../utils/util.js');
const api = require('../config/api.js');
/**
 * Promise封装wx.checkSession
 */
function checkSession() {
  return new Promise(function(resolve, reject) {
    wx.checkSession({
      success: function() {
        resolve(true);
      },
      fail: function() {
        reject(false);
      }
    })
  });
}
/**
 * Promise封装wx.login
 */
function login() {
  return new Promise(function(resolve, reject) {
    wx.login({
      success: function(res) {
        if (res.code) {
          resolve(res);
        } else {
          reject(res);
        }
      },
      fail: function(err) {
        reject(err);
      }
    });
  });
}
/**
 * 调用微信登录
 */
function loginByWeixin(userInfo) {
  return new Promise(function(resolve, reject) {
    return login().then((res) => {
      //登录远程服务器
      util.request(api.AuthLoginByWeixin, {
        code: res.code,
        userInfo: userInfo
      }, 'POST').then(res => {
        if (res.errno === 0) {
          //存储用户信息
          wx.setStorageSync('userInfo', res.data.userInfo);
          wx.setStorageSync('token', res.data.token);
          resolve(res);
        } else {
          reject(res);
        }
      }).catch((err) => {
        reject(err);
      });
    }).catch((err) => {
      reject(err);
    })
  });
}
/**
 * 判断用户是否登录
 */
function checkLogin() {
  return new Promise(function(resolve, reject) {
    if (wx.getStorageSync('userInfo') && wx.getStorageSync('token')) {
      checkSession().then(() => {
        resolve(true);
      }).catch(() => {
        reject(false);
      });
    } else {
      reject(false);
    }
  });
}
module.exports = {
  loginByWeixin,
  checkLogin,
};
package com.zlj.ssm.wxcontroller;
/**
 * @Autho donkee
 * @Since 2022/6/27
 */
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.alibaba.fastjson.JSONObject;
import com.zlj.ssm.annotation.LoginUser;
import com.zlj.ssm.model.UserInfo;
import com.zlj.ssm.model.WxLoginInfo;
import com.zlj.ssm.model.WxUser;
import com.zlj.ssm.service.UserToken;
import com.zlj.ssm.service.UserTokenManager;
import com.zlj.ssm.service.WxUserService;
import com.zlj.ssm.util.JacksonUtil;
import com.zlj.ssm.util.ResponseUtil;
import com.zlj.ssm.util.UserTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import javax.servlet.http.HttpServletRequest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * 鉴权服务
 */
@Slf4j
@RestController
@RequestMapping("/wx/auth")
public class WxAuthController {
    @Autowired
    private WxMaService wxService;
    @Autowired
    private WxUserService userService;
    /**
     * 微信登录
     *
     * @param wxLoginInfo
     *            请求内容,{ code: xxx, userInfo: xxx }
     * @param request
     *            请求对象
     * @return 登录结果
     */
    @PostMapping("login_by_weixin")
    public Object loginByWeixin(@RequestBody WxLoginInfo wxLoginInfo, HttpServletRequest request) {
        //客户端需携带code与userInfo信息
        String code = wxLoginInfo.getCode();
        UserInfo userInfo = wxLoginInfo.getUserInfo();
        if (code == null || userInfo == null) {
            return ResponseUtil.badArgument();
        }
        //调用微信sdk获取openId及sessionKey
        String sessionKey = null;
        String openId = null;
        try {
            long beginTime = System.currentTimeMillis();
            //
            WxMaJscode2SessionResult result = this.wxService.getUserService().getSessionInfo(code);
//            Thread.sleep(6000);
            long endTime = System.currentTimeMillis();
            log.info("响应时间:{}",(endTime-beginTime));
            sessionKey = result.getSessionKey();//session id
            openId = result.getOpenid();//用户唯一标识 OpenID
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (sessionKey == null || openId == null) {
            log.error("微信登录,调用官方接口失败:{}", code);
            return ResponseUtil.fail();
        }else{
            log.info("openId={},sessionKey={}",openId,sessionKey);
        }
        //根据openId查询wx_user表
        //如果不存在,初始化wx_user,并保存到数据库中
        //如果存在,更新最后登录时间
        WxUser user = userService.queryByOid(openId);
        if (user == null) {
            user = new WxUser();
            user.setUsername(openId);
            user.setPassword(openId);
            user.setWeixinOpenid(openId);
            user.setAvatar(userInfo.getAvatarUrl());
            user.setNickname(userInfo.getNickName());
            user.setGender(userInfo.getGender());
            user.setUserLevel((byte) 0);
            user.setStatus((byte) 0);
            user.setLastLoginTime(new Date());
            user.setLastLoginIp(IpUtil.client(request));
            user.setShareUserId(1);
            userService.add(user);
        } else {
            user.setLastLoginTime(new Date());
            user.setLastLoginIp(IpUtil.client(request));
            if (userService.updateById(user) == 0) {
                log.error("修改失败:{}", user);
                return ResponseUtil.updatedDataFailed();
            }
        }
        // token
        UserToken userToken = null;
        try {
            userToken = UserTokenManager.generateToken(user.getId());
        } catch (Exception e) {
            log.error("微信登录失败,生成token失败:{}", user.getId());
            e.printStackTrace();
            return ResponseUtil.fail();
        }
        userToken.setSessionKey(sessionKey);
        log.info("SessionKey={}",UserTokenManager.getSessionKey(user.getId()));
        Map<Object, Object> result = new HashMap<Object, Object>();
        result.put("token", userToken.getToken());
        result.put("tokenExpire", userToken.getExpireTime().toString());
        userInfo.setUserId(user.getId());
        if (!StringUtils.isEmpty(user.getMobile())) {// 手机号存在则设置
            userInfo.setPhone(user.getMobile());
        }
        try {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String registerDate = df.format(user.getAddTime() != null ? user.getAddTime() : new Date());
            userInfo.setRegisterDate(registerDate);
            userInfo.setStatus(user.getStatus());
            userInfo.setUserLevel(user.getUserLevel());// 用户层级
            userInfo.setUserLevelDesc(UserTypeEnum.getInstance(user.getUserLevel()).getDesc());// 用户层级描述
        } catch (Exception e) {
            log.error("微信登录:设置用户指定信息出错:"+e.getMessage());
            e.printStackTrace();
        }
        result.put("userInfo", userInfo);
        log.info("【请求结束】微信登录,响应结果:{}", JSONObject.toJSONString(result));
        return ResponseUtil.ok(result);
    }
    /**
     * 绑定手机号码
     *
     * @param userId
     * @param body
     * @return
     */
    @PostMapping("bindPhone")
    public Object bindPhone(@LoginUser Integer userId, @RequestBody String body) {
        log.info("【请求开始】绑定手机号码,请求参数,body:{}", body);
        String sessionKey = UserTokenManager.getSessionKey(userId);
        String encryptedData = JacksonUtil.parseString(body, "encryptedData");
        String iv = JacksonUtil.parseString(body, "iv");
        WxMaPhoneNumberInfo phoneNumberInfo = null;
        try {
            phoneNumberInfo = this.wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
        } catch (Exception e) {
            log.error("绑定手机号码失败,获取微信绑定的手机号码出错:{}", body);
            e.printStackTrace();
            return ResponseUtil.fail();
        }
        String phone = phoneNumberInfo.getPhoneNumber();
        WxUser user = userService.selectByPrimaryKey(userId);
        user.setMobile(phone);
        if (userService.updateById(user) == 0) {
            log.error("绑定手机号码,更新用户信息出错,id:{}", user.getId());
            return ResponseUtil.updatedDataFailed();
        }
        Map<Object, Object> data = new HashMap<Object, Object>();
        data.put("phone", phone);
        log.info("【请求结束】绑定手机号码,响应结果:{}", JSONObject.toJSONString(data));
        return ResponseUtil.ok(data);
    }
    /**
     * 注销登录
     */
    @PostMapping("logout")
    public Object logout(@LoginUser Integer userId) {
        log.info("【请求开始】注销登录,请求参数,userId:{}", userId);
        if (userId == null) {
            return ResponseUtil.unlogin();
        }
        try {
            UserTokenManager.removeToken(userId);
        } catch (Exception e) {
            log.error("注销登录出错:userId:{}", userId);
            e.printStackTrace();
            return ResponseUtil.fail();
        }
        log.info("【请求结束】注销登录成功!");
        return ResponseUtil.ok();
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package cn.binarywang.wx.miniapp.api;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
public interface WxMaService {
    String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
    String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
    WxMaJscode2SessionResult jsCode2SessionInfo(String var1) throws WxErrorException;
    boolean checkSignature(String var1, String var2, String var3);
    String getAccessToken() throws WxErrorException;
    String getAccessToken(boolean var1) throws WxErrorException;
    String get(String var1, String var2) throws WxErrorException;
    String post(String var1, String var2) throws WxErrorException;
    <T, E> T execute(RequestExecutor<T, E> var1, String var2, E var3) throws WxErrorException;
    void setRetrySleepMillis(int var1);
    void setMaxRetryTimes(int var1);
    WxMaConfig getWxMaConfig();
    void setWxMaConfig(WxMaConfig var1);
    WxMaMsgService getMsgService();
    WxMaMediaService getMediaService();
    WxMaUserService getUserService();
    WxMaQrcodeService getQrcodeService();
    WxMaTemplateService getTemplateService();
    WxMaAnalysisService getAnalysisService();
    WxMaCodeService getCodeService();
    WxMaJsapiService getJsapiService();
    WxMaSettingService getSettingService();
    WxMaShareService getShareService();
    WxMaRunService getRunService();
    WxMaSecCheckService getSecCheckService();
    void initHttp();
    RequestHttp getRequestHttp();
}
package com.zlj.ssm.wxcontroller;
import java.util.HashMap;
import java.util.Map;
import com.zlj.ssm.annotation.LoginUser;
import com.zlj.ssm.model.WxUser;
import com.zlj.ssm.service.WxUserService;
import com.zlj.ssm.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
 * 用户服务
 */
@Slf4j
@RestController
@RequestMapping("/wx/user")
@Validated
public class WxUserController {
  @Autowired
  private WxUserService userService;
  /**
   * 用户个人页面数据
   * <p>
   * @param userId
   *            用户ID
   * @return 用户个人页面数据
   */
  @GetMapping("index")
  public Object list(@LoginUser Integer userId, @RequestHeader("X-OA-token") String token) {
    log.info("【请求开始】用户个人页面数据,请求参数,userId:{}", userId);
    log.info("【请求开始】用户个人页面数据,请求参数,token:{}", token);
    if (userId == null) {
      log.error("用户个人页面数据查询失败:用户未登录!!!");
      return ResponseUtil.unlogin();
    }
    WxUser wxUser = userService.selectByPrimaryKey(userId);
    Map<Object, Object> data = new HashMap<Object, Object>();
    data.put("metting_pubs", wxUser.getUserLevel());
    data.put("metting_joins",wxUser.getUserLevel());
    return ResponseUtil.ok(data);
  }
}

4.微信表情包存储问题

工具->多账号调试->测试号(熊猫)->个人中心->点击登录->微信直接登录->允许(直接这样会报错,需要将MySQL安装的地方,将里面my.ini的utf8修改为utf8mb4,并且重启服务里的mysql)->重新尝试登录

目录
相关文章
|
2月前
|
小程序 JavaScript 前端开发
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
uni-app开发微信小程序:四大解决方案,轻松应对主包与vendor.js过大打包难题
740 1
|
2月前
|
小程序
小程序提交数据到后台做加法运算
小程序提交数据到后台做加法运算
28 0
|
10天前
|
人工智能 小程序 JavaScript
【一步步开发AI运动小程序】十四、主包超出2M大小限制,如何将插件分包发布?
本文介绍了如何从零开始开发一个AI运动小程序,重点讲解了通过分包技术解决程序包超过2M限制的问题。详细步骤包括在uni-app中创建分包、配置`manifest.json`和`pages.json`文件,并提供了分包前后代码大小对比,帮助开发者高效实现AI运动功能。
|
2月前
|
开发框架 小程序 JavaScript
小程序代码丢失!反编译找回
小程序源代码的容易获取问题确实存在一些潜在的安全隐患。然而,现在的小程序开发框架采用像 Babel 这样的打包工具,将 JavaScript 逻辑代码混合在一个文件中并进行转编译,使其变得难以理解。
54 0
小程序代码丢失!反编译找回
|
2月前
|
小程序 Java
小程序访问java后台失败解决方案
小程序访问java后台失败解决方案
53 2
|
2月前
|
小程序 JavaScript Java
小程序访问java后台
小程序访问java后台
30 1
|
2月前
|
小程序 安全 数据库连接
为什么已经提交的小程序无法连接后台服务?
【10月更文挑战第17天】为什么已经提交的小程序无法连接后台服务?
94 0
|
4月前
|
存储 小程序 Java
【小程序分包】小程序包大于2M,来这教你分包啊
本文介绍了如何通过分包解决uniapp小程序包体积过大的问题。由于版本升级导致包体积超过2M,即使压缩静态资源也无法满足发布要求。文章详细讲解了分包的原因、步骤及注意事项,并提供了实操示例,帮助读者理解并实现小程序分包,从而减小主包大小
215 1
【小程序分包】小程序包大于2M,来这教你分包啊
|
2月前
|
小程序 算法 前端开发
微信小程序---授权登录
微信小程序---授权登录
104 0
|
2月前
|
小程序 Java
小程序通过get请求提交数据到java后台
小程序通过get请求提交数据到java后台
32 0