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

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

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)->重新尝试登录

目录
相关文章
|
自然语言处理 搜索推荐 小程序
微信公众号接口:解锁公众号开发的无限可能
微信公众号接口是微信官方提供的API,支持开发者通过编程与公众号交互,实现自动回复、消息管理、用户管理和数据分析等功能。本文深入探讨接口的定义、类型、优势及应用场景,如智能客服、内容分发、电商闭环等,并介绍开发流程和工具,帮助运营者提升用户体验和效率。未来,随着微信生态的发展,公众号接口将带来更多机遇,如小程序融合、AI应用等。
|
10月前
|
JSON 运维 安全
当“企业微信iPad协议”潜入深夜值班室:一段代码引发的零号群风暴
深夜突现群聊异常,运维紧急排查发现:有人利用企业微信iPad协议将群控脚本植入系统,导致用户被反复踢出。追溯根源,为降本增效,团队此前绕开官方接口,自建网关解析iPad协议事件流,实现群自动化。但协议高自由度伴生风险,一次逻辑误判便引发雪崩。经加固幂等性、引入审计队列与双重签名,终控危机。技术无畏,亦需敬畏——能力越强,责任越重。
600 3
|
11月前
|
算法 iOS开发 CDN
“企业微信iPad协议”第 0x04 天:当朋友圈接口在凌晨 2:14 突然返回 404
新品上线紧急任务:300位经销商朋友圈同步海报。突破官方限制,利用企业微信iPad协议私有接口,自动化上传发布。凌晨遭遇404,迅速定位并修复算法版本问题,最终高效完成推送,点赞超4200。技术在文档之外,也在边界之内。
437 0
|
12月前
|
Shell Android开发 Python
微信多开脚本,微信双开器脚本插件,autojs开源代码分享
AutoJS脚本实现安卓端微信多开,通过无障碍服务 Python脚本提供跨平台解决方案,自动检测微信安装路径
|
11月前
|
iOS开发
“企业微信iPad协议”第0x0B次编译:当朋友圈接口在凌晨悄然返回空数组
新品海报发布失败,排查发现企业微信iPad端因本地时间偏差超60秒,导致`ext_ticket`校验失败。NTP校准后恢复正常。问题根源:独立加签逻辑对时间敏感,且错误不提示。精准时间成合规关键。
534 0
|
JSON 监控 小程序
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
1745 14
微信百度字节小程序包过大解决方案(实战经验总结)-优雅草卓伊凡|果果|小无
微信封号脚本插件,全自动批量投诉工具, vx隔空抓包封号思路【仅供学习参考用途】
这是一款针对微信投诉自动化处理的工具插件,通过模拟点击操作实现批量投诉功能。相比手动投诉,该插件效率更高、成功率更有保障。
|
XML 数据处理 数据安全/隐私保护
微信卡片生成器在线制作,微信xml链接代码,xml卡片生成器
这段代码实现了一个完整的数据处理程序,包含主程序、数据处理模块和工具模块。主程序负责启动和异常处理
微信养号脚本,导入手机号自动添加,autojs代码分享
这段代码实现了基本的微信自动添加好友功能,包括读取手机号文件、启动微信、搜索用户和发送
微信小程序数据绑定与事件处理:打造动态交互体验
在上一篇中,我们学习了搭建微信小程序开发环境并创建“Hello World”页面。本文深入探讨数据绑定和事件处理机制,通过具体案例帮助你打造更具交互性的小程序。数据绑定使用双花括号`{{}}`语法,实现页面与逻辑层数据的动态关联;事件处理则通过`bind`或`catch`前缀响应用户操作。最后,通过一个简单的计数器案例,巩固所学知识。掌握这些核心技能,将助你开发更复杂的小程序。