小程序授权登录前后端对接及用户信息完善

news/2024/9/20 0:24:42

对接后台登录流程

微信官方早都已经禁止开发者直接通过 api 获取用户信息数据了,大家拿个用户的 openid 注册好,剩下的让用户填写就行了。

先上官方的经典登录流程图:

登录流程时序

步骤拆分解析:

  1. 前端通过 调用官方 API wx.login,将回调中的 code 临时登陆凭证传递给(请求)后台
  2. 后台去请求微信的接口 https://api.weixin.qq.com/sns/jscode2session。具体用法参考 官方文档
  3. 后台请求该接口的响应成功的数据中可以拿到两个值 openidsession_key其中 openid 是唯一值,可以当作用户标识,比如判断该用户是否存在,是否注册该用户等。session_key 自行处理。

如果需要获取用户信息(现在用户信息毛都没有,获取也没用,别获取了),需要在 wx.login 之前调用 wx.getUserProfilerawDatasignature 联合 code 一并传递给后台,后台通过 session_keyrawData反解析 signature 的正确性。

根据现在微信官方的说法,注册时添加微信用户真实信息(头像昵称)是不可能的,前后端交互时,通过 wx.login 传递一个 code 仅注册就可以,其它参数目前完全没用

前端代码

不是我不用 wx.getUserProfile,而是这个 api 真没啥信息可获取了,老老实实拿个 openid 注册就行了。

wx.login({success(res) {wx.request({url: 'http://localhost:8888/testApi/wx/login',data: {// encryptedData 和 iv 是用来解析私密用户信息的,但是现在啥也获取不到了,所以没用code: res.code,// encryptedData: InfoRes.encryptedData,// iv: InfoRes.iv,// rawData: InfoRes.rawData,// signature: InfoRes.signature,},}).then((res) => {// 登录认证成功,后台一般会返回登陆凭证(token),存储使用即可});},fail(err) {console.log(err.errMsg);},
});

后端代码

请求第三方(微信)示例

请求第三方接口,这里给出两种获取第三方接口的代码方式,任选其中一种即可。

  1. pom 中集成 httpclient 包。

HttpClientUtils.java

public class HttpClientUtil {public static String doGet(String url, Map<String, String> param) {// 创建Httpclient对象CloseableHttpClient httpclient = HttpClients.createDefault();String resultString = "";CloseableHttpResponse response = null;try {// 创建uriURIBuilder builder = new URIBuilder(url);if (param != null) {for (String key : param.keySet()) {builder.addParameter(key, param.get(key));}}URI uri = builder.build();// 创建http GET请求HttpGet httpGet = new HttpGet(uri);// 执行请求response = httpclient.execute(httpGet);// 判断返回状态是否为200if (response.getStatusLine().getStatusCode() == 200) {resultString = EntityUtils.toString(response.getEntity(), "UTF-8");}} catch (Exception e) {e.printStackTrace();} finally {try {if (response != null) {response.close();}httpclient.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}public static String doGet(String url) {return doGet(url, null);}public static String doPost(String url, Map<String, String> param) {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建参数列表if (param != null) {List<NameValuePair> paramList = new ArrayList<>();for (String key : param.keySet()) {paramList.add(new BasicNameValuePair(key, param.get(key)));}// 模拟表单UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);httpPost.setEntity(entity);}// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {e.printStackTrace();} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}public static String doPost(String url) {return doPost(url, null);}public static String doPostJson(String url, String json) {// 创建Httpclient对象CloseableHttpClient httpClient = HttpClients.createDefault();CloseableHttpResponse response = null;String resultString = "";try {// 创建Http Post请求HttpPost httpPost = new HttpPost(url);// 创建请求内容StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);httpPost.setEntity(entity);// 执行http请求response = httpClient.execute(httpPost);resultString = EntityUtils.toString(response.getEntity(), "utf-8");} catch (Exception e) {e.printStackTrace();} finally {try {response.close();} catch (IOException e) {e.printStackTrace();}}return resultString;}
}

使用

Map<String, String> params = new HashMap<>();
// .... 参数添加 params.put("...","...")
String s = HttpClientUtil.doPost(url, params);
SONObject object = JSON.parseObject(s);
  1. 使用 Springboot 自带的 RestTemplate

RestTemplateUtil

public class RestTemplateUtil {public static JSONObject doPost(String url, MultiValueMap<String, Object> param){RestTemplate restTemplate=new RestTemplate();String s = restTemplate.postForObject(url, param, String.class);return JSONObject.parseObject(s);}
}

使用

MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
// .... 参数添加 params.add("...","...")
JSONObject object = RestTemplateUtil.doPost(url, params);

登录流程对接

// 现在 rawData 和 signature 已经没什么用了,所以这两个参数相关的逻辑可以删除,此处保留仅做记录
public R wxLogin(String code) {String url = "https://api.weixin.qq.com/sns/jscode2session";MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();params.add("appid",appid);params.add("secret",secret);params.add("js_code",code);params.add("grant_type",grantType);JSONObject object = RestTemplateUtil.doPost(url, params);System.out.println(object);//接收微信接口服务 获取返回的参数,这里拿到 openid 就足够了,后边的签名校验没啥必要String openid = object.getString("openid");String sessionKey = object.getString("session_key");//校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)// String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);// System.out.println(signature2);// System.out.println(openid);// if(!signature.equals(signature2)){//     return R.fail("签名校验失败");// }// SONObject rawDataJson = JSONObject.parseObject(rawData);// return R.ok(rawDataJson);// --------这里可以使用 openid 判断用户是否注册,将用户信息插入数据库
}

获取用户信息

通过 API 调用方式直接获取用户信息的方式已经完全没有了,只能让用户自己手动完善个人信息,类似于表单填写,但在此基础上,微信官方提供了相应的开放能力。

此处使用原生的小程序做示例,Taro 和 uniapp 的使用逻辑相同。

获取用户昵称

小程序的 input 组件配置 type="nickname"

<input type="nickname" model:value="{{ nameValue }}" placeholder="请输入昵称" />
Page({data: {nameValue: '',},onLoad(options) {const { name } = options;this.setData({nameValue: name,});},onSubmit() {// 此处可将填充的用户昵称提交给后端做更新console.log(this.data.nameValue);},
});

获取用户昵称示意图

获取用户头像

小程序的 button 组件需设置 open-type="chooseAvatar",并绑定对应的事件,获取用户的(上传)头像临时地址,将其传给后端进行信息保存。

<button open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar"><image src="{{ avatarUrl }}" />
</button>
const defaultAvatarUrl = 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0';Page({data: {avatarUrl: defaultAvatarUrl,},async onChooseAvatar(e) {const { avatarUrl = '' } = e.detail;const { data, code } = await uploadImg(avatarUrl);  // 此处将头像上传到后端,并返回图片 url 地址code === 200 &&this.setData({avatarUrl: data,});},
});

获取用户头像示意图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/57779.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Zabbix03 Zabbix自动化运维和性能优化高可性, Zabbix用Grafana图形展示

Zabbix 网络发现 专门有个进程扫描机器,比较耗资源,不太好(除非公司不大,添加的主机不多)Zabbix 自动注册 资源消耗少。agent必须是主动模式Zabbix API 实现自动化运维 先登录获取token,再携带token获取其他资源Zabbix 优化可以查看队列了解 Zabbix 性能状态 #web网页左侧…

第十四讲:答疑文章(一):日志和索引相关问题

第十四讲:答疑文章(一):日志和索引相关问题 简概:​ 到目前为止,我已经收集了 47 个问题,很难通过今天这一篇文章全部展开。所以,我就先从中找了几个联系非常紧密的问题,串了起来,希望可以帮你解决关于日志和索引的一些疑惑。而其他问题,我们就留着后面慢慢展开吧。…

大模型api实战-open.bigmodel.cn

注册登录后在个人中心的API keys中找到并复制推荐使用SDK,在虚拟环境安装 pip install zhipuai编辑python代码访问API获取响应 from zhipuai import ZhipuAI client = ZhipuAI(api_key="0c6df39e71b0a7340f221fddc1ddb711.au66Z02fXWc7SJBB") response = client.cha…

焦煤

这种走势概率大 目前在走3-5的跌势

n00bzCTF 2024

n00bzCTF 2024 Passwordless 给了源码 #!/usr/bin/env python3 from flask import Flask, request, redirect, render_template, render_template_string import subprocess import urllib import uuid global leetapp = Flask(__name__) flag = open(/flag.txt).read() leet=u…

linux虚拟机(centos)搭建sqli-labs

1.开启小皮2.查看文件位置 配置文件路径为/usr/local/phpstudy/soft [root@localhost soft]# cd /www/admin/localhost_80 [root@localhost soft]# pwd /usr/local/phpstudy/soft网站根目录为/www/admin/localhost_80/wwwroot [root@localhost localhost_80]# cd wwwroot [root…

Zabbix01 Zabbix安装和基础功能

商业监控方案#从各个地区来监测网络情况 http://ping.chinaz.com/ 站长之家 免费 https://www.jiankongbao.com/ 监控宝 ...#云服务自带云监控系统 Zabbix 架构#zabbix web为php程序 如果公司规模小,zabbix server,db和zabbix web装在一台机器上 如果公司规模大,…

【赛后反思】洛谷基础赛 #15 「LAOI」Round 6 考后总结(待补完)

待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完待补完LGR-198-Div.3 考后总结 又要掉分了:展开目录 目录LGR-198-Div.3 考后总结A [太阳]] 请…