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

news/2024/7/20 2:19:30 标签: 小程序, 微信

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


http://www.niftyadmin.cn/n/5116255.html

相关文章

组件通信$refs | $parent |$root

父组件传值子组件用Props 子组件传值父组件用$emit 父组件直接还可以直接取子组件的值用$refs 父组件直接从子子组件中获取值$refs 不建议使用会增加组件之间的耦合度&#xff0c;一般用于第三方插件的封装 ref如果绑定在dom节点上&#xff0c;拿到的就是原生dom节点。 ref如…

React hooks介绍及使用

介绍&#xff1a; React hooks 是 React 16.8 版本引入的新特性&#xff0c;它允许你在无需编写类组件的情况下&#xff0c;能够使用状态和其他 React 特性。它是基于函数组件的&#xff0c;使得函数组件也能够拥有类组件的状态和生命周期等特性&#xff0c;同时减少了处理一些…

Plonky2:最好的SNARKs和STARKs

1. 引言 Plonky2为Polygon团队2022年1月发起的项目。其定位为ZKP证明系统。 开源代码实现见&#xff1a; https://github.com/0xPolygonZero/plonky2&#xff08;Rust 汇编&#xff09; Plonky2可解锁当今2大主流ZKP类型——SNARKs和STARKs的扩容优势。 每个ZKP证明系统都有…

jdk17运行程序报错module java.base does not open java.lang.reflect to unnamed module @

背景 jdk17运行程序报错module java.base does not open java.lang.reflect to unnamed module 解决方案 增加配置 --add-opens java.base/java.langALL-UNNAMED --add-opens java.base/sun.net.utilALL-UNNAMED --add-opens java.base/java.lang.reflectALL-UNNAMED启动jar…

【斗破年番】官方终于回应,萧潇删减不属实,两线索佐证,彩鳞咖位不会降

【侵权联系删除】【文/郑尔巴金】 斗破苍穹年番动画虽然火爆&#xff0c;但是问题也很多&#xff0c;动不动就上演一出魔改&#xff0c;引发粉丝们的疯狂吐槽。先是萧炎与美杜莎女王的陨落心炎失身戏份遭删减&#xff0c;如今当萧炎回蛇人族&#xff0c;又魔改了美杜莎女王怀孕…

py文件全自动打包成spec文件

说明&#xff1a;自动当前根目录下所有py文件生成spec文件&#xff0c;直接运行pyinstaller进行打包即可。直接打包成单执行文件。 代码如下&#xff1a; import ospathex []def recursion(path, main):if path[:1] ! /:path /listpath os.listdir(path)for item in listp…

【Javascrpt】比较,逻辑运算符

目录 比较运算符 逻辑运算符 &&(与&#xff09; ||&#xff08;或&#xff09; 两真&#xff08;||左侧为真&#xff0c;||右侧为真&#xff09; 两假&#xff08;||左侧为假&#xff0c;右侧为假&#xff09; 一真一假&#xff08;||一侧为假&#xff0c;另一侧为…

ArGIS Engine专题(15)之GP模型在地图服务与地图服务之间实现叠置分析

前一篇文章已经介绍过导入要素范围与地图服务的叠加分析,相当于单要素与多要素之间的分析,这篇文章介绍地图服务与地图服务之间的叠加分析,即是多要素有多要素之间的相交分析,功能基本类似。 一、结果预览 二、需求简介 以下是一些常见的业务场景: (1)空间规划和土地…