热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第三方登录之微信扫码登录

文章目录1.申请微信接入:2.项目环境搭建:3.后端Controller接口:4.HTML页面代码:5.测试结果࿱


文章目录

    • 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文件&#xff1a;
因为所需要这4个参数&#xff0c;所以直接配置在yaml文件中&#xff0c;使用时直接在类中直接通过&#64;Value注解引入即可


  1. appid&#xff1a;
  2. appsecret&#xff1a;
  3. scope: snsapi_login
  4. callBack&#xff1a;

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

这里需要一个工具类HttpRequestUtils &#xff0c;用于发起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;/*** &#64;author: libo* &#64;date: 2020/11/21 20:49* &#64;motto: 即使再小的帆也能远航*/
public class HttpRequestUtils {private static CloseableHttpClient httpClient;static {PoolingHttpClientConnectionManager cm &#61; new PoolingHttpClientConnectionManager();cm.setMaxTotal(100);cm.setDefaultMaxPerRoute(20);cm.setDefaultMaxPerRoute(50);httpClient &#61; HttpClients.custom().setConnectionManager(cm).build();}public static String httpGet(String url) {CloseableHttpResponse response &#61; null;BufferedReader in &#61; null;String result &#61; "";try {HttpGet httpGet &#61; new HttpGet(url);RequestConfig requestConfig &#61; RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();httpGet.setConfig(requestConfig);httpGet.setConfig(requestConfig);httpGet.addHeader("Content-type", "application/json; charset&#61;utf-8");httpGet.setHeader("Accept", "application/json");response &#61; httpClient.execute(httpGet);in &#61; new BufferedReader(new InputStreamReader(response.getEntity().getContent()));StringBuffer sb &#61; new StringBuffer("");String line &#61; "";String NL &#61; System.getProperty("line.separator");while ((line &#61; in.readLine()) !&#61; null) {sb.append(line &#43; NL);}in.close();result &#61; sb.toString();} catch (IOException e) {e.printStackTrace();} finally {try {if (null !&#61; response) {response.close();}} catch (IOException e) {e.printStackTrace();}}return result;}
}

3.后端Controller接口&#xff1a;

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

4.HTML页面代码&#xff1a;

1.点击生成二维码页面&#xff1a;我这里是嵌入了一张微信的Logo图片&#xff0c;点击a标签跳转 weChatLogin.html在这里插入图片描述

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

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

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

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

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

5.测试结果&#xff1a;

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


  1. 访问login接口&#xff0c;点击logo图标
    在这里插入图片描述

  2. 扫码测试

在这里插入图片描述


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

在这里插入图片描述


6.补充说明&#xff1a;

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

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

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


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

推荐阅读
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • Windows7 64位系统安装PLSQL Developer的步骤和注意事项
    本文介绍了在Windows7 64位系统上安装PLSQL Developer的步骤和注意事项。首先下载并安装PLSQL Developer,注意不要安装在默认目录下。然后下载Windows 32位的oracle instant client,并解压到指定路径。最后,按照自己的喜好对解压后的文件进行命名和压缩。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
author-avatar
悍受蓁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有