官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

本文主要记录小程序实现微信登陆功能,后端为Java开发。

在开发之前我们先看一下官方提供的时序图,了解一下我们的大致开发流程:

大致了解流程之后,我们便可以着手开发了。

1. 前提

  • 一个可以测试的微信小程序

  • 此微信小程序的APPID和APPscret(至开发者后台获取)

2. 开发流程

从时序图我们可以了解到流程大致分为两步:

  • 小程序端获取code后传给Java后台
  • Java后台获取code后向微信后台接口获取open_id

2.1 小程序端

在微信小程序的前端调用wx.login()获取一个code,这个code就像是我们去微信后台服务器获取用户信息的一个钥匙,微信通过获取这个code的过程给用户一个选择是否授权的选择,如果用户选择了授权就会返回一个code。这个code是一次性的,也是有时限的。由于我在Java后台进行了一次数据校验,所以我也会从getUserInfo接口中获取相关数据。代码如下:

2.2 Java后端接口

后端的流程我将其大致分为如下几点:

  • 接收小程序发送的code
  • 开发者服务器 登录凭证校验接口 appi + appsecret + code
  • 接收微信接口服务 获取返回的参数
  • 校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
  • 根据返回的User实体类,判断用户是否是新用户,是的话,将用户信息存到数据库;

获取openId

后台接受了code以后通过建立一个http请求去访问微信后台服务器拉取这个用户的openid,如果一切正常就会得到这个用户对应这个小程序的openid。

请求的地址:

https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

通过GET方式访问,其中的参数分别是:

  • appid:小程序的appid

  • secret:小程序的appsecret

  • js:小程序前端传来的code

  • grant_type:这个不用修改,表示授权的类型

请求工具类代码如下:(APPID自行替换)

public class WechatUtil {public static JSONObject getSessionKeyOrOpenId(String code) {String requestUrl = "https://api.weixin.qq.com/sns/jscode2session";Map<String, String> requestUrlParam = new HashMap<>();// https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=164113089&lang=zh_CN//小程序appIdrequestUrlParam.put("appid", WXConstant.APPID);//小程序secretrequestUrlParam.put("secret", WXConstant.SECRET);//小程序端返回的coderequestUrlParam.put("js_code", code);//默认参数requestUrlParam.put("grant_type", "authorization_code");//发送post请求读取调用微信接口获取openid用户唯一标识JSONObject jsonObject = JSON.parseObject(HttpClientUtil.doPost(requestUrl, requestUrlParam));return jsonObject;}
}

HTTP工具类如下:

需要添加相关依赖。

<!-- http请求工具包依赖 -->
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version>
</dependency>
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;}
}

接口代码

具体代码如下所示:

判断用户是否存在后的代码根据自己的业务逻辑进行修改即可。

@PostMapping("/wx/login")
public R user_login(@RequestParam(value = "code", required = false) String code,@RequestParam(value = "rawData", required = false) String rawData,@RequestParam(value = "signature", required = false) String signature) {// 用户非敏感信息:rawData// 签名:signatureJSONObject rawDataJson = JSON.parseObject(rawData);// 1.接收小程序发送的code// 2.开发者服务器 登录凭证校验接口 appi + appsecret + codeJSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);// 3.接收微信接口服务 获取返回的参数String openid = SessionKeyOpenId.getString("openid");String sessionKey = SessionKeyOpenId.getString("session_key");// 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);if (!signature.equals(signature2)) {return R.error().message("签名校验失败");}// 5.根据返回的User实体类,判断用户是否是新用户,是的话,将用户信息存到数据库;LambdaQueryWrapper<User> lqw = Wrappers.lambdaQuery();lqw.eq(User::getOpenId, openid);User user = userService.getOne(lqw);if (user == null) {// 用户信息入库String nickName = rawDataJson.getString("nickName");String avatarUrl = rawDataJson.getString("avatarUrl");user = new User();user.setOpenId(openid);user.setAvatar(avatarUrl);user.setNickName(nickName);userService.save(user);}return R.ok().data(user);
}

微信小程序实现微信登录详解(JAVA后台)相关推荐

  1. php小程序onload,微信小程序 loading 组件实例详解

    这篇文章主要介绍了微信小程序 loading 组件实例详解的相关资料,需要的朋友可以参考下 loading通常使用在请求网络数据时的一种方式,通过hidden属性设置显示与否 主要属性: wxml 显 ...

  2. 微信小程序(三)详解篇

    一.什么是小程序(了解) 小程序是一种不需要下载安装即可使用的应用,它实现了应用"触手可及"的梦想,用户扫一扫或者搜一下即可打开应用.也体现了"用完即走"的理念 ...

  3. 微信小程序02【配置详解、生命周期-app对象使用、页面跳转详解】

    学习地址:https://www.bilibili.com/video/BV1sx411z77P 笔记01:https://blog.csdn.net/weixin_44949135/article/ ...

  4. 微信小程序框架(二)-全面详解(学习总结---从入门到深化)

    目录 组件_基础视图 容器 view 文本 text 图片 image 组件_滑块视图容器 基本实现 Swiper常用属性说明 组件_滚动视图区域 水平滚动 垂直滚动 常用属性 组件_icon 图标使 ...

  5. 微信小程序框架(四)-全面详解(学习总结---从入门到深化)

    目录 路由_navigateTo 页面跳转 携带参数 返回上一级页面 路由_redirectTo 页面跳转 路由_reLaunch 页面跳转 路由_switchTab 实现 tabbar 页面跳转 交 ...

  6. 新手微信小程序制作教程步骤详解!

    制作微信小程序方法: 1.在微信公众平台上申请一个小程序账号,申请完成之后需要进行微信认证,并且需要缴纳300元的认证费用.如果不缴纳300元的费用,微信小程序商城没有开通支付功能. 2.新建一个空白 ...

  7. 微信小程序框架(一)-全面详解(学习总结---从入门到深化)

    目录 小程序与普通网页开发的区别 体验小程序 微信小程序账号申请 微信小程序开发者工具 下载安装 创建项目 开发者工具说明 小程序目录结构 描述整体的 app 描述各自页面的 page 全局配置_Pa ...

  8. 微信小程序python解析获取用户手机号_微信小程序获取用户手机号详解

    最近在做一款微信小程序,需要获取用户手机号,具体步骤如下: 流程图: 1.首先,客户端调用wx.login,回调数据了包含jscode,用于获取openid(用户唯一标识)和sessionkey(会话 ...

  9. 小程序01——微信小程序开发平台下载详解

    犹记得当时为了安装微信小程序开发平台费了不少功夫,这里花一点时间粗略介绍一下,日后若有时间再进行补充: 1.进入微信公众平台官网下载 https://mp.weixin.qq.com/ 把鼠标移至小程 ...

  10. 微信小程序按钮Button使用详解

    最近在出微信小程序系列教程 顺手写了点博客 欢迎大家关注 button 用来实现按钮点击效果,本文章效果如下: 1 wxml 文件中 在这里我就放了三个普通的按钮 <view class=&qu ...

最新文章

  1. python list.pop 的方法的使用
  2. 又是华为!名校的差距太扎心!清华 2020 年毕业生就业质量报告出炉
  3. 解决Chrome浏览器启动速度慢的问题
  4. python导入包库的两种语句import 和 from … import
  5. 在EXCEL中如何将一列中的相同值的数据行找出来?
  6. python | 删除两个指定字符串之间的内容
  7. Codeforces 699D Fix a Tree 并查集
  8. Adwonder笔记
  9. leetcode之53.最大子序和
  10. 23种设计模式(三)组件协作之策略模式
  11. HDU4757 Tree(可持久化Trie)
  12. 牛x!一个比传统数据库快 100-1000 倍的数据库!
  13. 云承软件和云溪哪个好_多工序开料机的软件对接及注意事项
  14. Maven笔记 - 第十章
  15. LINUX操作命令汇总(zt)
  16. 绘制一张好看的散点图及pearson和spearman相关性分析的选择
  17. 世界陶瓷卫浴100强榜单发布!
  18. 【复现】CNVD-2020-10487-Tomcat-Ajp-lfi
  19. 首金奥运健儿杨倩,获得金牌和奖金缴纳个税吗?雅戈尔赠送她一套房,交税吗?
  20. 在网页中内嵌视频,例如优酷

热门文章

  1. mysql存储引擎分类
  2. sql server 查询当前月份日期列表数据
  3. 《HiWind企业快速开发框架实战》(2)使用HiWind创建自己的项目
  4. treeview子节点文本过长超过DIV自动换行CSS解决
  5. Lenovo E46A-Win 7_无线灯亮但无法启动(耽误3天以上您信吗.....)问题: wlan autoconfig 依赖服务或组无法启动...
  6. Linux学习之路(2-1)文件、目录与磁盘格式
  7. 输入一正整数,将各数字反转后输出
  8. HTTP代理服务器 - CONNECT SSL/TLS 原理
  9. 利用Expect实现telnet自动登录并执行command
  10. 怎么查询共享使用人_为什么使用“共享充电宝”的人越来越少?