登录流程

1、通过调用wx.login获取登录凭证(code)

  • uni-app通过调用uni.login

2、前端将code提交给服务器,springboot访问 auth.code2Session,使用 code 换取 openid、unionid、session_key 等信息。

3、完成登录操作,返回token给前端。

测试发现,个人小程序无法获取unionid

步骤一

通过调用wx.login获取登录凭证(code)

示例:uni-app项目中,使用uni.login获取登录凭证(code)

// 微信小程序
// #ifdef MP-WEIXINuni.login({provider: 'weixin',success: function(loginRes) {if (loginRes.errMsg == "login:ok") {//提交code到服务器,完成登录操作doWxLogin({code: loginRes.code}).then(res => {console.log(res)//。。。})}}
});// #endif

wx.login

调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。

code,用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用 auth.code2Session,使用 code 换取 openid、unionid、session_key 等信息。

  • openid:指的微信用户在微信的某个应用中的唯一标识。
  • unionid:指的微信用户的唯一标识。(相当于微信用户ID)
  • 微信某个应用:指的是 公众号、小程序、开放平台等。
  • 若要开发多个微信应用,应当获取微信用户的唯一标识 unionid。

目前小程序开发者可以通过 wx.login 接口直接获取用户的 openId 与 unionId 信息,实现微信身份登录。对许多小程序使用场景,用户无需提供头像昵称。如有必要场景需收集用户头像昵称,可在个人中心或设置等页面让用户完善个人资料。如业务需获取用户头像、昵称,可以使用「头像昵称填写能力」。

wx.getUserProfile

获取用户信息。页面产生点击事件(例如 buttonbindtap 的回调中)后才可调用,每次请求都会弹出授权窗口,用户同意后返回 userInfo

属性 类型 说明 最低版本
signature string 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,详见 用户数据的签名验证和加解密 2.10.4
encryptedData string 包括敏感数据在内的完整用户信息的加密数据,详见 用户数据的签名验证和加解密 2.10.4
iv string 加密算法的初始向量,详见 用户数据的签名验证和加解密 2.10.4

2022年11月8日24时起,已废弃。wx.getUserProfile,在uni-app中是uni.getUserProfile。若该方法未失效,可使用code换取的session_key将encryptedData解密,获取用户信息。

步骤二

前端将code提交给服务器,springboot访问 auth.code2Session,使用 code 换取 openid、unionid、session_key 等信息。

  • 在换取到openid/unionid后,查找用户表,若有匹配的用户则自动登录,否则自动注册一个账号再完成自动登录,返回token到前端。以实现微信小程序快速登录。
  • 现在无法通过解密encryptedData(wx.getUserProfile得到)获取用户的昵称、头像、性别、地区等数据,得提供一个类似“个人中心“的页面让用户自己完善(如果用户需要)。

springboot示例

配置文件

配置文件application.properties

# 微信小程序配置
wx.appId=wxd95.......de4cfe
wx.appSecret=76b497f2.........ea08645f8824
wx.online_people_url=https://api.weixin.qq.com/sns/jscode2session

登录微信公众平台获取小程序的AppID、AppSecret

Controller

@ApiOperation(value = "微信小程序自动登录/注册")
@GetMapping("/wxauth/signin/{code}")
public DataVo<String> doWxLogin(@PathVariable @ApiParam(value = "wx.login获取的登录凭证",required = true) String code){return authService.doWxLogin(code);
}

Service

使用注解@Value获取配置在springboot配置文件中的参数:

//https://api.weixin.qq.com/sns/jscode2session
@Value("${wx.online_people_url}")
private String ONLINE_PEOPLE_URL;//小程序的AppID
@Value("${wx.appId}")
private String APP_ID;//小程序的AppSecret
@Value("${wx.appSecret}")
private String SECRET;

获取session_key等

访问 auth.code2Session,使用 code 换取 openid、unionid、session_key 等信息:

  • 封装方法getSessionKeyByWX,使用 code 换取 openid、session_key
  • getSessionKey,调用getSessionKeyByWX,获取session_key
/*** 微信登陆,通过code获取session_key、openid。*     session_key:用于解密 前端wx.getUserProfile(以前是wx.getUserInfo)接口 返回的加密的用户数据,头像、昵称、性别、地区等信息(2022-11,微信已弃用该接口,已无法通过其获取用户信息)。*     openid:用户的身份标识,每个用户在每个公众号或者小程序中都有一个唯一openid,跨公众号/小程序时openid不相同。若想在公众号、小程序、开放平台等地方使用不同账号,则使用openid作为用户标识。** @param code 通过wx.login获取到的用户的code(登录凭证)* @return 返回session_key、openid、isSuccess,通过isSuccess是否为true来判断是否成功获取到session_key、openid。*         示例:{"session_key":"VtyIGnq9U2E8c95XUm2SeQ==","openid":"o60_YvksCvHRpajcmiLVAUYybXcM","isSuccess":"false"}*/
public String getSessionKeyByWX(String code) {String baseUrl = ONLINE_PEOPLE_URL + "?appid=" + APP_ID + "&secret=" + SECRET + "&js_code=" + code + "&grant_type=authorization_code";log.info("---微信登陆,通过code获取sessionkey");log.info("---baseUrl ="+baseUrl);//使用 hutool 发起get请求//基于JDK的HttpUrlConnection封装String result = HttpUtil.get(baseUrl);log.info("---拿到GET结果 ="+result);//使用 hutool 解析jsonJSONObject jsonObject = JSONUtil.parseObj(result);if(!jsonObject.isNull("session_key")) {//成功获取到session_key等数据return result.substring(0,result.length()-1)+",\"isSuccess\":\"true\"}";}else {//失败,没获取到session_key等数据return "{\"session_key\":\"\",\"openid\":\"\",\"isSuccess\":\"false\"}";}
}/*** 微信登陆,通过code获取session_key* @param code 通过wx.login获取到的用户的code(登录凭证)* @return 返回session_key,用于解密 前端wx.getUserProfile接口 返回的加密的用户数据(2022-11,微信已弃用该接口,已无法通过其获取用户信息)。*/
public DataVo<String> getSessionKey(String code) {//使用 hutool 解析jsonJSONObject json = JSONUtil.parseObj(getSessionKeyByWX(code));if(json.getBool("isSuccess")) {log.info("isSuccess = true,成功获取到session_key。session_key = "+json.getStr("session_key"));return JSONResult.ok(json.getStr("session_key"));}else {// 记录日志log.error("获取sessionkey失败! code = "+code);return JSONResult.errorMsg("获取sessionkey失败! code = "+code);}
}

获取用户数据

使用 session_key 解密encryptedData数据,获取用户信息(已废弃,encryptedData中没有用户数据):调用getUserInfo前,先调用getSessionKey获取session_key。

/*** 微信登陆,解密encryptedData数据。*     但因为微信调整了用户信息权限,只能获取unionid,不能再获取头像、昵称、性别、地区等信息。*     unionid,微信用户的唯一标识(相当于微信用户ID),若想在公众号、小程序、开放平台等地方使用同一个账号,则使用unionid* @param encryptedData 被加密的数据* @param signature 加密秘钥(即getSessionKey方法返回的sessionKey)* @param iv 偏移量* @return 解密后的encryptedData(用户信息)*/
public DataVo<String> getUserInfo(String encryptedData, String signature, String iv){// 被加密的数据byte[] dataByte = Base64.getDecoder().decode(encryptedData);// 加密秘钥byte[] keyByte = Base64.getDecoder().decode(signature);// 偏移量byte[] ivByte = Base64.getDecoder().decode(iv);log.error("被加密的数据 encryptedData= "+encryptedData);log.error("加密秘钥 sessionKey= "+signature);log.error("偏移量 iv= "+iv);//hutool AES解密AES aes = new AES("CBC","PKCS7Padding",keyByte,ivByte);String res = aes.decryptStr(dataByte);log.info("---解密后 ="+res);// 解密并返回return JSONResult.ok(res);
}

登录

doWxLogin,调用getSessionKeyByWX,获取openid,实现自动登录

/*** 微信小程序自动登录/注册* @param code wx.login获取的登录凭证*/
public DataVo doWxLogin(String code){//使用登录凭证code获取openidJSONObject json = JSONUtil.parseObj(getSessionKeyByWX(code));if(json.getBool("isSuccess")) {// 通过 json.getStr("openid") 获取openid// 根据openid判断新用户还是老用户//   老用户,登录操作,返回token//   新用户,则随机注册一个账号(用户名、账号、用户ID),登录操作,返回token//...// return xxx(登陆成功)}else {// 记录日志log.error("获取sessionkey失败! code = "+code);return JSONResult.errorMsg("登录失败! 无法获取openid!");}
}

说明

本博客中的案例,使用的maven依赖如下:http请求、AES解密均使用的是hutool

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.2</version><relativePath/> <!-- lookup parent from repository -->
</parent><!--        启用web支持-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency><!--        hutool-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.10</version>
</dependency>

笔记摘自:CSDN-、楽. 、 知乎-微信小程序获取用户unionId 、 微信官方文档 • 小程序

微信小程序登陆,后端接口实现 - springboot相关推荐

  1. 解决微信小程序请求后端接口碰到合法域名的问题 http-405j及java接口和数据接口的概念区分

    合法域名的问题 http-405 解决方案: @Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse res ...

  2. 微信小程序调用后端接口

    wx.request var data = {name:'小张爱敲代码' } wx.request({url: '',data: datasuccess(res) {conso.log(res)}})

  3. 微信小程序与后端Java接口交互-图书搜索实现

    完整微信小程序(Java后端) 技术贴目录清单页面(必看) 我们模拟实现一个微信小程序端关键字图书,然后显示图书列表的功能,如下图: 实现大体思路,前端用户输入关键字,通过bindtap事件,事件里得 ...

  4. 微信小程序——登陆凭证校验报错{errcode:40029,errmsg:invalid code, hints: [ req_id: weh8ka0297hc58 ]}

    微信小程序登陆校验时需要使用临时登录凭证code ,appID和appsecret来向微信服务接口来获取 session_key 和 openid .但是后台向微信服务器请求时得到的一直是{" ...

  5. PHP —— 用 ThinkPHP5.0 实现微信小程序登陆

    PHP -- 用 ThinkPHP5.0 实现微信小程序登陆 <工欲善其事,必先利其器> 大家好,之前学习了 原生 PHP 和框架,今天我们运用框架 TP5.0 来实现一下微信小程序的用户 ...

  6. 微信小程序调用支付接口支付(tp5、小程序)

    微信小程序调用支付接口支付 今天记录一下学习的小程序调用微信支付接口 一.先理清一下调起微信支付的整个流程. 1.就是先调用微信的支付统一下单api获取到prepay_id 2.然后后端再将这个pre ...

  7. 微信小程序链接后台接口,进行数据交互

    微信小程序链接后台接口,进行数据交互 新手学微信小程序,设计页面还可以,有没有让进行数据交互的时候就不知道怎么弄了,下面就记录一下我是怎么进行交互的 1.登陆微信小程序平台,进入首页,点击开发设置 2 ...

  8. 微信小程序登陆凭证校验出现{errcode:40029,errmsg:invalid code, hints: [ req_id: weh8ka0297hc58 ]}

    问题描述: 微信小程序登陆校验时需要使用临时登录凭证code ,appID和appsecret获取 session_key 和 openid 等.但是后台向微信服务器请求时一直报{"errc ...

  9. 小程序---调用后端接口的方法

    小程序---调用后端接口的方法 学习小程序一段时间了,写页面对我来说没有任何问题.最近学习如何请求后端接口,本来想请求项目中正在用的接口,可是无缘,微信小程序不允许.官方给出的提示是,接口必须有域名且 ...

  10. 微信小程序之获取接口数据展示

    上篇说到获取编辑框文本,没看过去看看. 本片介绍简单的接口数据获取,并且展示,采取模拟数据,拉取数据方式方法.文章最后附上DEMO 本篇暂未考虑美化问题,只看功能.如图: 一.简单介绍 1> w ...

最新文章

  1. AD中批量增加带密码用户
  2. 硬件开源产品_5种适合户外活动的开源硬件产品
  3. ras的c语言源代码文档,µMore(µITRON操作系统)--功能概况
  4. extjs chart无法在panel中显示_HighChart教程:Swift中的Highcharts iOS库
  5. mysql企业版功能列表_大型企业数据库服务首选,AliSQL这几大企业级功能你了解几个?...
  6. php 警告和错误屏蔽
  7. 终端会话和孤儿进程组(POSIX-2.2.2.52)--解释问题
  8. Windows下JNI的使用教程
  9. 从数据治理、数据资产管理,到数据中台的落地实战!
  10. 西门子TIA portal中如何安装FANUC机器人的GSD文件
  11. 摄像头设计工程师面试技巧_系统设计面试准备的5个技巧
  12. SH-SSS丨《ISSD: 基于迭代式语音分离的说话人日志系统》论文线上分享
  13. DEC6713开发板的摸索(1)
  14. 实数截断式保留两位小数
  15. 梯度下降法和最速下降法区别
  16. javabean 一些这方面的快捷键
  17. ZStack——存储模型:主存储和备份存储
  18. 《陶行知教育文集》读后感
  19. oracle fx成立时间,oracle 日期格式FM/FX和日期后缀SP/TH/SPTH/THSP
  20. canvas 绘制图片

热门文章

  1. python批量修改文件扩展名
  2. 如何查询SCI和EI检索号
  3. Camera | 4.瑞芯微平台MIPI摄像头应用程序编写
  4. Cay S.Horstmann:从Java新特性看Java的未来
  5. [RK3399/RK3328][Android10.0] storage:u盘/移动硬盘 每次开机都提示需要格式化
  6. Shell 字符串转数组的三种方式
  7. OCR图文识别软件是怎么保存页面图像的
  8. java 判断手机访问_java后台如何判断是移动端还是pc端的访问请求
  9. TableLayout表格布局详解
  10. 3DMax模型输入到WPF中运行