文章目录

  • 1. 申请微信接入:
  • 2. 项目环境搭建:
  • 3.后端Controller接口:
  • 4.HTML页面代码:
  • 5.测试结果:
  • 6.补充说明:

小伙伴们有各种疑问可以去参考官方文档进行详细的学习下 微信开发文档 ,此次介绍的将是前后端不分离的微信扫码登录

微信登录开发流程:

  1. 申请微信接入
  2. 生成登录二维码
  3. 用户扫码并授权
  4. 调用回调方法
  5. 通过code去获取用户信息带到页面展示

官方流程图:

1. 申请微信接入:

先提醒下各位:申请微信接入很麻烦,本人因为公司业务需要,用的是公司申请好的。还没自己去申请过。

先去到 微信开放平台 https://open.weixin.qq.com


申请一个网站应用 (要审核通过之后才能用)


注:

  1. appid和appSecret就是调用微信接口的凭证
  2. 授权回调域:调用微信接口生成的二维码地址,用户扫码并授权后,会重定向到回调地址
  3. 因为在本地localhost进行测试,如果回调地址为localhost第三方微信将无法进行跳转。原因是外网访问不到本地,怎么办?解决办法:那就使用 ngrok 内网穿透把本地项目服务映射到公网,所以在测试时填写的回调地址是内网穿透时的访问域名
  4. 如果不知道内网穿透的小伙伴,建议先看看 Sunny-Ngrok 内网穿透的使用

如果不知道内网穿透的小伙伴,建议先看看 Sunny-Ngrok 内网穿透的使用

启动 Sunny-Ngrok 内网穿透的客户端,先将本地服务映射到公网。

2. 项目环境搭建:

下面正式开始代码部分,创建SpringBoot项目并导入所需Jar包:
环境:JDK1.8,SpringBoot2.3.5.RELEASE

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version></dependency><dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>20200518</version></dependency>
</dependencies>

yaml文件:
因为所需要这4个参数,所以直接配置在yaml文件中,使用时直接在类中直接通过@Value注解引入即可

  1. appid:
  2. appsecret:
  3. scope: snsapi_login
  4. callBack:
server:port: 80spring:thymeleaf:prefix: classpath:/templates/suffix: .htmlmvc:static-path-pattern: classpath:/static/wechat:#微信接口的AppID:appid: #微信接口的AppSecret:appsecret: #应用授权作用域(网站应用目前的固定写法就是snsapi_login)scope: snsapi_login#扫码之后的回调地址:callBack: http://wechatlogin.free.idcfengye.com/callBack

这里需要一个工具类HttpRequestUtils ,用于发起http请求。可以将代码直接复制过去用

package com.login.utils;import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** @author: libo* @date: 2020/11/21  20:49* @motto: 即使再小的帆也能远航*/
public class HttpRequestUtils {private static CloseableHttpClient httpClient;static {PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();cm.setMaxTotal(100);cm.setDefaultMaxPerRoute(20);cm.setDefaultMaxPerRoute(50);httpClient = HttpClients.custom().setConnectionManager(cm).build();}public static String httpGet(String url) {CloseableHttpResponse response = null;BufferedReader in = null;String result = "";try {HttpGet httpGet = new HttpGet(url);RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();httpGet.setConfig(requestConfig);httpGet.setConfig(requestConfig);httpGet.addHeader("Content-type", "application/json; charset=utf-8");httpGet.setHeader("Accept", "application/json");response = httpClient.execute(httpGet);in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));StringBuffer sb = new StringBuffer("");String line = "";String NL = System.getProperty("line.separator");while ((line = in.readLine()) != null) {sb.append(line + NL);}in.close();result = sb.toString();} catch (IOException e) {e.printStackTrace();} finally {try {if (null != response) {response.close();}} catch (IOException e) {e.printStackTrace();}}return result;}
}

3.后端Controller接口:

package com.login.controller;import com.login.utils.HttpRequestUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;/*** @author: libo* @date: 2020/11/21  21:32* @motto: 即使再小的帆也能远航*/
@Controller
@CrossOrigin
@SuppressWarnings("unchecked")
public class weChatController {@Value(value = "${wechat.appid}")private String appid;@Value(value = "${wechat.appsecret}")private String appsecret;@Value(value = "${wechat.scope}")private String scope;@Value(value = "${wechat.callback}")private String callBack;/*生产二维码链接进行扫码登录*/@RequestMapping("/login")public String index(Model model) throws Exception {String oauthUrl = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";String redirect_uri = URLEncoder.encode(callBack, "utf-8");oauthUrl = oauthUrl.replace("APPID", appid).replace("REDIRECT_URI", redirect_uri).replace("SCOPE", scope);model.addAttribute("oauthUrl", oauthUrl);return "login";}/*生成自定义二维码*/@RequestMapping("/custom")public String custom(Model model) throws UnsupportedEncodingException {String redirect_uri = URLEncoder.encode(callBack, "utf-8");model.addAttribute("appid", appid);model.addAttribute("scope", scope);model.addAttribute("redirect_uri", redirect_uri);return "custom";}/*回调方法*/@RequestMapping("/callBack")public String callBack(String code,Map<String,Object> map) {//1.通过code获取access_tokenString url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";url = url.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);String tokenInfoStr = HttpRequestUtils.httpGet(url);JSONObject tokenInfoObject = new JSONObject(tokenInfoStr);//2.通过access_token和openid获取用户信息String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";userInfoUrl = userInfoUrl.replace("ACCESS_TOKEN", tokenInfoObject.getString("access_token")).replace("OPENID", tokenInfoObject.getString("openid"));String userInfoStr = HttpRequestUtils.httpGet(userInfoUrl);map.put("token", tokenInfoStr);/*转为JSON*/JSONObject user = new JSONObject(userInfoStr);/*只获取openid并返回,openid是微信用户的唯一标识,userInfoStr里面有用户的全部信息*/String openid = user.getString("openid");map.put("openid", openid);/*获取用户头像url*/String headimgurl = user.getString("headimgurl");map.put("headimgurl", headimgurl);/*获取用户昵称*/String nickname = user.getString("nickname");map.put("nickname", nickname);/*获取用户性别*/int sex = user.getInt("sex");map.put("sex", sex);/*获取用户国家*/String country = user.getString("country");map.put("country", country);/*获取用户省份*/String province = user.getString("province");map.put("province", province);/*获取用户城市*/String city = user.getString("city");map.put("city", city);return "callBack";}}

4.HTML页面代码:

1.点击生成二维码页面:我这里是嵌入了一张微信的Logo图片,点击a标签跳转 weChatLogin.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>wechat登录</title>
</head>
<body><a th:href="${oauthUrl}"><img src="../static/wechat_logo.png" alt="微信登录"></a>
</body>
</html>

2.回调方法后返回用户信息页面 callBack.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>授权结果页</title>
</head>
<body><h2>用戶,授权成功!</h2><br><h3>通过code获取access_token 结果:</h3><p th:text="${token}"></p><h3>通过access_token获取用户信息 结果:</h3>头像:<img th:src="${headimgurl}" alt="用户头像"><br/>openid:<span th:text="${openid}"></span><br/>昵称:<span th:text="${nickname}"></span><br/>性别:<span th:text="${sex}"></span><br/>国家:<span th:text="${country}"></span><br/>省份:<span th:text="${province}"></span><br/>城市:<span th:text="${city}"></span></body>
</html>

3.内嵌(自定义二维码) custom.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>内嵌(自定义二维码)</title>
</head>
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
<body><center><div id="login_container"></div></center>
<script th:inline="javascript">var obj = new WxLogin({self_redirect:true,id:"login_container",appid: [[${appid}]],scope: [[${scope}]],redirect_uri: [[${redirect_uri}]],state: "",style: "",href: ""});
</script>
</body>
</html>

5.测试结果:

使用内网穿透的域名来访问接口哦,因为已经在公网映射到本地项目了

  1. 访问login接口,点击logo图标

  2. 扫码测试

  1. 授权后调用回调方法,拿到用户信息放到页面展示
    注:openid是微信用户的唯一id

6.补充说明:

到这里呢微信登录SpringBoot前后端不分离就差不多了,在这里想给大家提一下如果是前后端分离怎么做?

1.回调地址一般是网站的主页对吧,例如:www.abc.com
2.前端按钮通过appid和回调地址生成二维码
3.用户扫码授权之后,微信接口会再通过回调地址重定向回主页 www.abc.com。在这是会有一个名为code的参数
4.此时前端拥有code之后,传到后端接口方法中去,后端通过code获取用户信息。再返回前端

总结为一句话:1.www.adc.com主页生成二维码,2.扫码授权登录,3.拿code参数去获取用户信息

如果我们有再三思考的机会,几乎没有一件事情是不能被简化的。

第三方登录之微信扫码登录相关推荐

  1. 【网课平台】Day10.对接第三方:实现微信扫码登录

    文章目录 一.需求:微信扫码登录 1.接口文档 2.开发环境准备 3.接入分析 4.接口定义 5.申请令牌 6.查询用户信息 7.保存用户信息 一.需求:微信扫码登录 (和第三方对接的流程) 1.接口 ...

  2. 使用码上登录实现微信扫码登录

    现如今使用微信的人越来越多,很多网站都实现了让用户直接扫码就能登录网站,正是这种方式给用户带来了极多的好处,最重要的是用户不用担心自己总记不住账户密码,从而登录不了网站. 为了方便用户登录,我也想接入 ...

  3. 整合第三方登录之微信扫码登录

    文章目录 前言 一.引入相关依赖 二.操作步骤 1.生成微信登录二维码 2.获取微信用户信息并实现微信注册登录 总结 前言 前置条件:具备微信开发者资质. 通过微信开放平台注册.完善开发者资料.申请开 ...

  4. Spring学习笔记(二十三)——实现网站微信扫码登录获取微信用户信息Demo

    目录 微信扫码登录介绍 开发步骤 微信扫码登录示例 微信开放文档 遇到的问题 使用第三方工具实现网站微信扫码登录 开发前介绍 开发步骤 微信扫码登录获取微信用户信息Demo实现流程 实现效果 实现过程 ...

  5. 个人开发者实现微信扫码登录

    使用码上登录中转微信扫码登录 使用之前最好有一个公网服务器,能够公网访问的 redis 和 mysql 数据库,并且能够部署公网访问的服务 码上登录是一个小程序,对个体开发者提供了免费的微信扫一扫登录 ...

  6. Vue+abp微信扫码登录

    最近系统中要使用微信扫码登录,根据微信官方文档和网络搜索相关文献实现了.分享给需要的人,也作为自己的一个笔记.后端系统是基于ABP的,所以部分代码直接使用了abp的接口,直接拷贝代码编译不通过. 注册 ...

  7. 微信开放平台开发——网页微信扫码登录(OAuth2.0)

    1.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供 ...

  8. 项目整合微信扫码登录功能

    项目整合微信登录功能 一.准备工作 https://open.weixin.qq.com 1.注册 2.邮箱激活 3.完善开发者资料 4.开发者资质认证 准备营业执照,1-2个工作日审批.300元 5 ...

  9. 通过微信扫码登录剖析 oauth2 认证授权技术

    本文目录 前言 趣味解读oauth2 oauth2精髓 oauth2核心概念 结合微信登录深刻理解oauht2 本文小结 前言 相信很多小伙伴在学习 JAVA 的过程中或多或少接触或者开发过类似于 x ...

最新文章

  1. 自然语言处理(NLP)之依存句法分析的可视化及图分析
  2. PopupWindow的使用
  3. 现金流为王!中小企业如何“疫”境求生?
  4. 【PAT甲级 U形打印】1031 Hello World for U (20 分) Java版 6/6通过
  5. C---编写程序:实现一个随堂测试,能进行加减乘除运算。要求如下:(1)随机产生两个1~10的正整数,在屏幕上输出题目,如:5+3=?(2)学生输入答案,程序检查学生输入答案是否正确,若正确,
  6. 我的一篇思想汇报——君子务本,本立而道生
  7. excel 文件导入数据库(java)
  8. Centos使用Cacti监控你的网络
  9. 活动目录的物理结构逻辑结构
  10. Simulink之晶闸管(可控硅SCR)
  11. 网络安全工具100强介绍与下载
  12. java永久区_方法区、永久代和元空间Metaspace
  13. 每日一题《青蛙跳步》
  14. LaTex Introduction 基础介绍
  15. github fork PR 的简单使用
  16. Tinyriscv FPGA移植
  17. 《Linux C编程从入门到精通》——1.4 Linux的常用命令
  18. 【C++FunCode】基于Funcode使用C++语言编写小游戏(小鲨鱼历险记)
  19. 大学生心理课程网课答案-【必看】
  20. Java帝国之宫廷内斗2(分布式事务消息队列、事务表)

热门文章

  1. 路由桥接 android连不上网,路由器桥接后上不了网几种解决办法
  2. Vue基操会了,还有必要学React么?
  3. 使用github提供的webhook服务完成自动部署网站
  4. 中国同步带轮市场趋势报告、技术动态创新及市场预测
  5. Android 12.0 修改wifi信号强度
  6. 苹果暗黑模式_苹果正式推送iOS13.4、iPadOS更新,微信安卓版暗黑模式来了,手机淘宝出现弹窗Bug,柔宇第二代折叠屏手机发布...
  7. 数据分析师岗位薪资多少?一张图告诉你答案
  8. 亿级数据mysql优化
  9. NSQ单节点和集群搭建
  10. Amaple.js框架详细介绍