小言_互联网的博客

一文学会微信WEB第三方登录

696人阅读  评论(0)

今天给大家分享一下微信WEB第三方登录:

一、提前工作:

(提前工作省略,腾讯要你提供什么,你就提供什么就好了。)

1.1、申请微信开放平台账号(https://open.weixin.qq.com/):

1.2、企业开发平台认证

1.3、创建网站应用,注意网站名称、网站logo这个会给用户直观显示的。

1.4、完成1.3需要等待审核1-7天,审核成功腾讯会给你提供AppID和AppSecret

1.5、配置回调地址(为了方便本地调试用的花生壳地址,也可以采用其他内网映射外网工具例如:ngrok):

二、查看微信开放文档pc网站登录流程:

微信文档登录流程:

  1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
  2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
  3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

腾讯官方提供的流程图:

 

 

三、微信提供两种二维码模式(我们来一一叙述):

第一种(跳转腾讯扫码页面):

3.1、第一步请求code: 

封装获取code访问URL:

https://open.weixin.qq.com/connect/qrconnect?appid=wxea3axxxxx41a91a&redirect_uri=http://20y85987b7.51mypc.cn/&response_type=code&scope=snsapi_login&state=gd5q4tcr#wechat_redirect

3.2、代码演示:

service层拼接url参数:

postman访问获取用户点击codeURl前端也可以写死,不过不能防止csrf攻击,主要是存放一下state参数:

访问获取code地址:

扫码登录:

重定向到我们提供给腾讯回调地址并且给我们带过来code以及state参数:

我们拿着临时凭证(code)去获取accessToken以及用户信息:

controller层:

service层:

postman请求获取用户信息:

以上就是第一种第三方登录方式。

第二种(网站内嵌微信登录二维码)

第一步:查阅官方文档:

https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

第二步:写前端代码:

后续步骤和方案1一致:

登录:

跳转页面获取临时凭证code(第二种方法:state目前没存放session,大家有兴趣可以补一下)

拿着code获取用户信息:

四、分享代码:

4.1、pom文件:


  
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0 </modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot </groupId>
  7. <artifactId>spring-boot-starter-parent </artifactId>
  8. <version>2.3.2.RELEASE </version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>cn.cnbuilder.wechat </groupId>
  12. <artifactId>pc-login </artifactId>
  13. <version>0.0.1-SNAPSHOT </version>
  14. <name>pc-login </name>
  15. <description>Demo project for Spring Boot </description>
  16. <properties>
  17. <java.version>1.8 </java.version>
  18. <!-- lib versions -->
  19. <WxJava.version>3.3.5.B </WxJava.version>
  20. </properties>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot </groupId>
  24. <artifactId>spring-boot-starter-web </artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.springframework.boot </groupId>
  28. <artifactId>spring-boot-starter </artifactId>
  29. </dependency>
  30. <dependency>
  31. <groupId>mysql </groupId>
  32. <artifactId>mysql-connector-java </artifactId>
  33. <version>5.1.46 </version>
  34. </dependency>
  35. <dependency>
  36. <groupId>com.baomidou </groupId>
  37. <artifactId>mybatis-plus-boot-starter </artifactId>
  38. <version>3.0.7.1 </version>
  39. </dependency>
  40. <dependency>
  41. <groupId>org.projectlombok </groupId>
  42. <artifactId>lombok </artifactId>
  43. <optional>true </optional>
  44. </dependency>
  45. <dependency>
  46. <groupId>cn.hutool </groupId>
  47. <artifactId>hutool-all </artifactId>
  48. <version>4.1.21 </version>
  49. </dependency>
  50. <!--添加fastjson依赖-->
  51. <dependency>
  52. <groupId>com.alibaba </groupId>
  53. <artifactId>fastjson </artifactId>
  54. <version>1.2.28 </version>
  55. </dependency>
  56. <!--注解做映射-->
  57. <dependency>
  58. <groupId>org.springframework.boot </groupId>
  59. <artifactId>spring-boot-starter-data-jpa </artifactId>
  60. </dependency>
  61. <dependency>
  62. <groupId>org.apache.commons </groupId>
  63. <artifactId>commons-lang3 </artifactId>
  64. <version>3.8 </version>
  65. </dependency>
  66. </dependencies>
  67. <build>
  68. <plugins>
  69. <plugin>
  70. <groupId>org.springframework.boot </groupId>
  71. <artifactId>spring-boot-maven-plugin </artifactId>
  72. </plugin>
  73. </plugins>
  74. </build>
  75. </project>

4.2、controller:


  
  1. index controller
  2. package cn.cnbuilder.wechat.webLogin.controller;
  3. import cn.cnbuilder.wechat.webLogin.entity.R;
  4. import cn.cnbuilder.wechat.webLogin.service.WechatWebLoginService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.web.bind.annotation.*;
  8. import javax.servlet.http.HttpServletRequest;
  9. /**
  10. * 首页
  11. * create on 2020/08/07 by kingyifan
  12. */
  13. @RestController
  14. public class IndexController {
  15. @GetMapping(value = "/")
  16. public String getCreatCodeUrl() {
  17. return "wechat之web第三方登录工程";
  18. }
  19. }
  20. WechatWebLoginController:
  21. package cn.cnbuilder.wechat.webLogin.controller;
  22. import cn.cnbuilder.wechat.webLogin.service.WechatWebLoginService;
  23. import cn.cnbuilder.wechat.webLogin.entity.R;
  24. import org.springframework.beans.factory.annotation.Autowired;
  25. import org.springframework.web.bind.annotation.*;
  26. import javax.servlet.http.HttpServletRequest;
  27. /**
  28. * wechat之web端第三方登录
  29. * create on 2020/08/07 by kingyifan
  30. */
  31. @RestController
  32. @RequestMapping("/wechat")
  33. public class WechatWebLoginController {
  34. @Autowired
  35. private WechatWebLoginService wechatWebLoginService;
  36. /**
  37. * 获取生成用户点击之后能获取code的接口
  38. * 第一步:请求CODE
  39. * <p>
  40. * 第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),
  41. * 则可以通过在PC端打开以下链接:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
  42. * 若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。
  43. * 以上摘自-腾讯官方文档 :https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
  44. *
  45. * @param request 获取HttpServletRequest中session存放STATE
  46. * STATE 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
  47. * @return URL 微信登录请求地址
  48. */
  49. @GetMapping(value = "/getCreatCodeUrl")
  50. @ResponseBody
  51. public R getCreatCodeUrl(HttpServletRequest request) {
  52. String getCodeUrl = wechatWebLoginService.getCreatCodeUrl(request);
  53. return R.ok().data(getCodeUrl);
  54. }
  55. /**
  56. * 通过getCreatCodeUrl方法并且用户授权之后前端页面会拿到code参数,参数会直接拼接在回调地址后面
  57. * <p>
  58. * 通过code获取access_token、openid、unionid(当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。)
  59. *
  60. * @param request
  61. * @return
  62. */
  63. @GetMapping(value = "/getUserInfoByCode")
  64. @ResponseBody
  65. public R getUserInfoByCode(HttpServletRequest request) {
  66. //true:state是否存放session
  67. return wechatWebLoginService.getInfoByCode(request);
  68. }
  69. }

4.3、service:


  
  1. service接口:
  2. package cn.cnbuilder.wechat.webLogin.service;
  3. import cn.cnbuilder.wechat.webLogin.entity.R;
  4. import javax.servlet.http.HttpServletRequest;
  5. import java.util.Map;
  6. public interface WechatWebLoginService {
  7. String getCreatCodeUrl(HttpServletRequest request);
  8. R getInfoByCode(HttpServletRequest request );
  9. }
  10. serviceImpl:
  11. package cn.cnbuilder.wechat.webLogin.service.impl;
  12. import cn.cnbuilder.wechat.webLogin.entity.R;
  13. import cn.cnbuilder.wechat.webLogin.entity.WeChatUserInfo;
  14. import cn.cnbuilder.wechat.webLogin.entity.WechatBaseInfo;
  15. import cn.cnbuilder.wechat.webLogin.mapper.WechatUserInfoMapper;
  16. import cn.cnbuilder.wechat.webLogin.service.WechatWebLoginService;
  17. import cn.cnbuilder.wechat.webLogin.utils.WechatWebLoginUtil;
  18. import cn.hutool.core.util.RandomUtil;
  19. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  20. import org.apache.commons.lang3.StringUtils;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.stereotype.Service;
  23. import javax.servlet.http.HttpServletRequest;
  24. import javax.servlet.http.HttpServletResponse;
  25. @Service
  26. public class WechatWebLoginServiceImpl implements WechatWebLoginService {
  27. @Autowired
  28. private WechatUserInfoMapper wechatUserInfoMapper;
  29. @Override
  30. public String getCreatCodeUrl(HttpServletRequest request) {
  31. //state参数:用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
  32. //第一步生成随机的state参数 该参数可用于防止csrf攻击(跨站请求伪造攻击)
  33. String state = RandomUtil.randomString( 8);
  34. //第二步存放session
  35. request.getSession().setAttribute( "state", state);
  36. //获取用户点击url可以生成code的链接
  37. String getCodeUrl = WechatWebLoginUtil.getCodeUrl(state);
  38. return getCodeUrl;
  39. }
  40. /**
  41. * 根据code获取信息
  42. * 第一步:判断state是否和我们存放的state一致
  43. * <br> 不一致,则直接返回这是一次非腾讯官方的回调请求。
  44. * 第二步:判断用户是否同意登录(查看是否有code)
  45. * <br> 不同意:则直接返回登录失败
  46. * 第三步:判断code是否有效,是否是腾讯返回的
  47. * <br> 是:获取信息
  48. * <br> 否:这是一次无效的登录请求
  49. *
  50. * @param request
  51. */
  52. @Override
  53. public R getInfoByCode(HttpServletRequest request) {
  54. String isSetState = request.getParameter( "state");
  55. //是否存放State
  56. if (isSetState != null && StringUtils.isNotEmpty(isSetState)) {
  57. /**
  58. * 第一步
  59. * 查看state是否和我们存放的一致;
  60. */
  61. //微信给的state
  62. String wstate = request.getParameter( "state");
  63. //session中的state
  64. Object sstate = request.getSession().getAttribute( "state");
  65. if (StringUtils.isEmpty(sstate.toString()) || !sstate.equals(wstate)) {
  66. return R.error( 500, "恶意请求");
  67. }
  68. }
  69. /**
  70. * 第二步查看用户是否授权:
  71. * 用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
  72. * redirect_uri ? code = CODE & state = STATE
  73. * 若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
  74. 以上摘自微信官方文檔:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
  75. */
  76. //获取腾讯给的code
  77. String code = request.getParameter( "code");
  78. //判断是否是空的。
  79. if (StringUtils.isBlank(code) || StringUtils.isEmpty(code)) {
  80. return R.error( 500, "code为空!");
  81. }
  82. //调用微信通过code获取access_token接口
  83. WechatBaseInfo wechatBaseInfo = WechatWebLoginUtil.getBaseInfoByCode(code);
  84. if (wechatBaseInfo.getErrcode() != null) {
  85. return R.error( 500, wechatBaseInfo.getErrmsg());
  86. }
  87. //获取到基础开发信息之后,判断用户信息在db是否完整
  88. QueryWrapper<WeChatUserInfo> queryWrapper = new QueryWrapper<>();
  89. queryWrapper.eq( "openid", wechatBaseInfo.getOpenid());
  90. WeChatUserInfo dWeChatUserInfo = wechatUserInfoMapper.selectOne(queryWrapper);
  91. //用户信息不存在
  92. if (dWeChatUserInfo != null) {
  93. //如果db存在则直接返回,如果怕用户更改了资料也可以重新走一下获取用户信息接口
  94. return R.ok().data(dWeChatUserInfo);
  95. }
  96. //获取基础信息获取用户信息
  97. WeChatUserInfo wechatUserInfo = WechatWebLoginUtil.getUserInfoByOpenid(wechatBaseInfo);
  98. if (wechatUserInfo == null) {
  99. return R.error( 500, "用户信息获取失败!");
  100. }
  101. wechatUserInfoMapper.insert(wechatUserInfo);
  102. return R.ok().data(wechatUserInfo);
  103. }
  104. }

4.4、工具类:


  
  1. package cn.cnbuilder.wechat.webLogin.utils;
  2. import cn.cnbuilder.wechat.webLogin.entity.WeChatUserInfo;
  3. import cn.cnbuilder.wechat.webLogin.entity.WechatBaseInfo;
  4. import cn.hutool.http.HttpUtil;
  5. import cn.hutool.json.JSONObject;
  6. import cn.hutool.json.JSONUtil;
  7. import org.apache.commons.lang3.StringUtils;
  8. /**
  9. * 微信第三方web登录工具类
  10. * create on 2020.08.07 by kingyifan
  11. */
  12. public class WechatWebLoginUtil {
  13. //微信开放平台申请pc应用开发密钥 可以后期弄到配置文件动态获取
  14. public static String APPID = "xxxxxxxxx";
  15. public static String APPSECRET = "xxxxxxxxx";
  16. //-------------------------------------微信第三方登录信息------------------------------------------------//
  17. //获取codeurl下面是固定的
  18. public static String GETCODEURL = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
  19. //微信回调地址(这个地址可以说是前端页面,这个地址腾讯回调过来会在后面拼code参数)
  20. public static String REDIRECTURI = "http://20y85987b7.51mypc.cn/";
  21. //应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login
  22. public static String SCOPE = "snsapi_login";
  23. // 获取access_token 通过code获取access_token
  24. public static String ACCESSTOKENURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
  25. //根据openid获取用户信息接口地址
  26. public static String USERINFOURL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
  27. /**
  28. * 拼接获取code的:接口地址
  29. *
  30. * @param state 随机数 防止csrf攻击(跨站请求伪造攻击)
  31. * @return
  32. */
  33. public static String getCodeUrl(String state) {
  34. //替换appId、回调url 以及state参数
  35. return GETCODEURL.replace( "APPID", APPID).replace( "REDIRECT_URI", REDIRECTURI).replace( "SCOPE", SCOPE).replace( "STATE", state);
  36. }
  37. /**
  38. * 根据code获取用户基础开发信息、AccessToken、openId、unionId、refreshToken
  39. *
  40. * @param code 临时授权凭证
  41. * @return
  42. */
  43. public static WechatBaseInfo getBaseInfoByCode(String code) {
  44. //基础信息实体类
  45. WechatBaseInfo wechatBaseInfo = new WechatBaseInfo();
  46. //拼接获取access_token的请求地址
  47. String accessTokenUrl = ACCESSTOKENURL.replace( "APPID", APPID).replace( "SECRET", APPSECRET).replace( "CODE", code);
  48. //發送请求获取基础开发信息
  49. String getResponseInfo = HttpUtil.get(accessTokenUrl);
  50. if (StringUtils.isEmpty(getResponseInfo)) {
  51. wechatBaseInfo.setErrcode(- 1);
  52. wechatBaseInfo.setErrmsg( "错误请求");
  53. return wechatBaseInfo;
  54. }
  55. //把请求结果转成json对象
  56. JSONObject reObject = JSONUtil.parseObj(getResponseInfo);
  57. //判断是否有异常 比如code失效。。。。
  58. if (reObject.getInt( "errcode") != null) {
  59. /**
  60. * 错误返回样例:
  61. * {
  62. * "errcode":40029,
  63. * "errmsg":"invalid code"
  64. * }
  65. */
  66. wechatBaseInfo.setErrcode(reObject.getInt( "errcode"));
  67. wechatBaseInfo.setErrmsg(reObject.getStr( "errmsg"));
  68. return wechatBaseInfo;
  69. } else {
  70. /**
  71. *正确的返回:
  72. * {
  73. * "access_token":"ACCESS_TOKEN",
  74. * "expires_in":7200,
  75. * "refresh_token":"REFRESH_TOKEN",
  76. * "openid":"OPENID",
  77. * "scope":"SCOPE",
  78. * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
  79. * }
  80. */
  81. //接口调用凭证
  82. wechatBaseInfo.setAccess_token(reObject.getStr( "access_token"));
  83. //access_token接口调用凭证超时时间,单位(秒)
  84. wechatBaseInfo.setExpires_in(reObject.getStr( "expires_in"));
  85. //用户刷新access_token
  86. wechatBaseInfo.setRefresh_token(reObject.getStr( "refresh_token"));
  87. // 授权用户唯一标识
  88. wechatBaseInfo.setOpenid(reObject.getStr( "openid"));
  89. //用户授权的作用域,使用逗号(,)分隔
  90. wechatBaseInfo.setScope(reObject.getStr( "scope"));
  91. // unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。
  92. wechatBaseInfo.setUnionid(reObject.getStr( "unionid"));
  93. return wechatBaseInfo;
  94. }
  95. }
  96. /**
  97. * 根据基础开发信息获取用户信息
  98. *
  99. * @param wechatBaseInfo
  100. * @return
  101. */
  102. public static WeChatUserInfo getUserInfoByOpenid(WechatBaseInfo wechatBaseInfo) {
  103. WeChatUserInfo weChatUserInfo = new WeChatUserInfo();
  104. //拼接获取userinfo的请求地址
  105. String userInfoUrl = USERINFOURL.replace( "ACCESS_TOKEN", wechatBaseInfo.getAccess_token()).replace( "OPENID", wechatBaseInfo.getOpenid());
  106. //發送请求获取用户信息
  107. String getResponseInfo = HttpUtil.get(userInfoUrl);
  108. if (StringUtils.isEmpty(getResponseInfo)) {
  109. weChatUserInfo.setErrcode(- 1);
  110. weChatUserInfo.setErrmsg( "错误请求");
  111. return weChatUserInfo;
  112. }
  113. //把请求结果转成json对象
  114. JSONObject reObject = JSONUtil.parseObj(getResponseInfo);
  115. //判断是否有异常 比如无效的openId
  116. if (reObject.getInt( "errcode") != null) {
  117. /**
  118. * 错误的Json返回示例:
  119. * {
  120. * "errcode":40003,
  121. * "errmsg":"invalid openid"
  122. * }
  123. */
  124. weChatUserInfo.setErrcode(reObject.getInt( "errcode"));
  125. weChatUserInfo.setErrmsg(reObject.getStr( "errmsg"));
  126. return weChatUserInfo;
  127. } else {
  128. //普通用户的标识,对当前开发者帐号唯一
  129. weChatUserInfo.setOpenid(reObject.getStr( "openid"));
  130. //普通用户昵称
  131. weChatUserInfo.setNickname(reObject.getStr( "nickname"));
  132. //普通用户性别,1为男性,2为女性
  133. weChatUserInfo.setSex(reObject.getInt( "sex"));
  134. // 普通用户个人资料填写的省份
  135. weChatUserInfo.setProvince(reObject.getStr( "province"));
  136. //普通用户个人资料填写的城市
  137. weChatUserInfo.setCity(reObject.getStr( "city"));
  138. //国家,如中国为CN
  139. weChatUserInfo.setCountry(reObject.getStr( "country"));
  140. //TODO 请注意,在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况。 这里需要下载用户头像然后保存到自己的服务器 这一步省略。。。
  141. //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
  142. weChatUserInfo.setHeadimgurl(reObject.getStr( "headimgurl"));
  143. // 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
  144. weChatUserInfo.setPrivilege(reObject.getJSONArray( "privilege").toString());
  145. //用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
  146. weChatUserInfo.setUnionid(reObject.getStr( "unionid"));
  147. return weChatUserInfo;
  148. }
  149. }
  150. }

4.5、实体类:


  
  1. R:统一返回实体:
  2. package cn.cnbuilder.wechat.webLogin.entity;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class R extends HashMap<String, Object> {
  6. private static final long serialVersionUID = - 8713837118340960775L;
  7. public R() {
  8. put( "code", 200);
  9. put( "msg", "success");
  10. }
  11. public static R error() {
  12. return error( 500, "未知异常,请联系管理员");
  13. }
  14. public static R error(String msg) {
  15. return error( 500, msg);
  16. }
  17. public static R error(int code, String msg) {
  18. R r = new R();
  19. r.put( "code", code);
  20. r.put( "msg", msg);
  21. return r;
  22. }
  23. public static R ok(String msg) {
  24. R r = new R();
  25. r.put( "msg", msg);
  26. return r;
  27. }
  28. public static R ok(Map<String, Object> map) {
  29. R r = new R();
  30. r.putAll(map);
  31. return r;
  32. }
  33. public static R ok() {
  34. return new R();
  35. }
  36. public R message(String message) {
  37. this.put( "message", message);
  38. return this;
  39. }
  40. public R data(Object data) {
  41. this.put( "data", data);
  42. return this;
  43. }
  44. @Override
  45. public R put(String key, Object value) {
  46. super.put(key, value);
  47. return this;
  48. }
  49. public String getMessage() {
  50. return String.valueOf(get( "message"));
  51. }
  52. public Object getData() {
  53. return get( "data");
  54. }
  55. public Integer getCode() {
  56. return (Integer) get( "code");
  57. }
  58. }
  59. 微信第三方登录基础开发信息:
  60. package cn.cnbuilder.wechat.webLogin.entity;
  61. import lombok.Data;
  62. /**
  63. * 微信web登录基础开发信息
  64. * 文档地址:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
  65. */
  66. @Data
  67. public class WechatBaseInfo {
  68. /**
  69. * 接口调用凭证
  70. */
  71. private String access_token;
  72. /**
  73. * access_token接口调用凭证超时时间,单位(秒)
  74. */
  75. private String expires_in;
  76. /**
  77. * 用户刷新access_token
  78. */
  79. private String refresh_token;
  80. /**
  81. * 授权用户唯一标识
  82. */
  83. private String openid;
  84. /**
  85. * 用户授权的作用域,使用逗号(,)分隔
  86. */
  87. private String scope;
  88. /**
  89. * 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段
  90. */
  91. private String unionid;
  92. /**
  93. * 错误编码
  94. */
  95. private Integer errcode;
  96. /**
  97. * 错误信息
  98. */
  99. private String errmsg;
  100. }
  101. 用户信息实体:
  102. package cn.cnbuilder.wechat.webLogin.entity;
  103. import com.baomidou.mybatisplus.annotation.TableField;
  104. import com.baomidou.mybatisplus.annotation.TableName;
  105. import lombok.Data;
  106. import javax.persistence.Table;
  107. import javax.persistence.Transient;
  108. import javax.persistence.criteria.CriteriaBuilder;
  109. @Data
  110. @TableName("wechat_userinfo")
  111. public class WeChatUserInfo {
  112. /**
  113. * 普通用户的标识,对当前开发者帐号唯一
  114. */
  115. private String openid;
  116. /**
  117. * 普通用户昵称
  118. */
  119. private String nickname;
  120. /**
  121. * 普通用户性别,1为男性,2为女性
  122. */
  123. private Integer sex;
  124. /**
  125. * 普通用户个人资料填写的省份
  126. */
  127. private String province;
  128. /**
  129. * 普通用户个人资料填写的城市
  130. */
  131. private String city;
  132. /**
  133. * 国家,如中国为CN
  134. */
  135. private String country;
  136. /**
  137. * 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空
  138. */
  139. private String headimgurl;
  140. /**
  141. * 用户特权信息,json数组,如微信沃卡用户为(chinaunicom)
  142. */
  143. private String privilege;
  144. /**
  145. * 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。
  146. */
  147. private String unionid;
  148. /**
  149. * 错误编码
  150. */
  151. @TableField(exist = false)
  152. private Integer errcode;
  153. /**
  154. * 错误信息
  155. */
  156. @TableField(exist = false)
  157. private String errmsg;
  158. }

4.6、mapper文件:


  
  1. package cn.cnbuilder.wechat.webLogin.mapper;
  2. import cn.cnbuilder.wechat.webLogin.entity.WeChatUserInfo;
  3. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4. import org.apache.ibatis.annotations.Mapper;
  5. @Mapper
  6. public interface WechatUserInfoMapper extends BaseMapper <WeChatUserInfo> {
  7. }
  8. xml文件:
  9. <?xml version="1.0" encoding="UTF-8"?>
  10. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  11. <mapper namespace="cn.cnbuilder.wechat.webLogin.mapper.WechatUserInfoMapper">
  12. </mapper>

4.7、启动类:


  
  1. package cn.cnbuilder.wechat.webLogin;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class PcLoginApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(PcLoginApplication.class, args);
  8. }
  9. }

4.8、配置文件:


  
  1. application.yml文件:
  2. spring:
  3. profiles:
  4. active: dev #选择要用那个配置文件
  5. application-dev.yml文件:
  6. #端口号访问路径
  7. server:
  8. port: 12008
  9. servlet:
  10. context-path: /
  11. #spring
  12. spring:
  13. devtools:
  14. restart:
  15. enabled: true
  16. # mysql 配置
  17. datasource:
  18. driver-class-name: com.mysql.jdbc.Driver
  19. type: com.zaxxer.hikari.HikariDataSource
  20. url: jdbc:mysql://127.0.0.1/wechat_weblogin?useUnicode= true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL= true&serverTimezone=GMT%2B8
  21. username: root
  22. password: root
  23. hikari:
  24. ## 最小空闲连接数量
  25. minimum-idle: 5
  26. ## 空闲连接存活最大时间,默认600000(10分钟)
  27. idle-timeout: 180000
  28. ## 连接池最大连接数,默认是10
  29. maximum-pool-size: 10
  30. ## 此属性控制从池返回的连接的默认自动提交行为,默认值:true
  31. auto-commit: true
  32. ## 连接池名称
  33. pool-name: MyHikariCP
  34. ## 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟
  35. max-lifetime: 1800000
  36. ## 数据库连接超时时间,默认30秒,即30000
  37. connection-timeout: 30000
  38. ## 监听是否存活
  39. connection-test-query: SELECT 1
  40. servlet:
  41. multipart:
  42. enabled: true
  43. max-file-size: -1
  44. #mybatis
  45. mybatis-plus:
  46. mapper-locations: classpath:/mapper/*Mapper.xml
  47. #实体扫描,多个package用逗号或者分号分隔
  48. typeAliasesPackage: cn.cnbuilder.wechat.webLogin.entity
  49. global-config:
  50. # 数据库相关配置
  51. db-config:
  52. #主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
  53. id-type: id_worker
  54. #字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
  55. field-strategy: not_empty
  56. #驼峰下划线转换
  57. column-underline: true
  58. #数据库大写下划线转换
  59. # capital-mode: true
  60. #逻辑删除配置
  61. logic-delete-value: 0
  62. logic-not-delete-value: 1
  63. #刷新mapper 调试神器
  64. refresh: true
  65. # 原生配置
  66. configuration:
  67. map-underscore-to-camel-case: true
  68. cache-enabled: false

4.9、sql:


  
  1. CREATE TABLE `wechat_userinfo` (
  2. `id` int( 11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  3. `openid` varchar( 32) DEFAULT '' COMMENT '普通用户的标识,对当前开发者帐号唯一',
  4. `nickname` varchar( 50) DEFAULT '' COMMENT '普通用户昵称',
  5. `sex` int( 2) DEFAULT '0' COMMENT '普通用户性别,1为男性,2为女性',
  6. `province` varchar( 30) DEFAULT '' COMMENT ' 普通用户个人资料填写的省份',
  7. `city` varchar( 30) DEFAULT '' COMMENT '普通用户个人资料填写的城市',
  8. `country` varchar( 30) DEFAULT '' COMMENT '国家,如中国为CN',
  9. `headimgurl` varchar( 200) DEFAULT '' COMMENT '用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空',
  10. `privilege` varchar( 20) DEFAULT '' COMMENT '用户特权信息,json数组,如微信沃卡用户为(chinaunicom)',
  11. `unionid` varchar( 32) DEFAULT '' COMMENT '用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。',
  12. PRIMARY KEY ( `id`) USING BTREE
  13. ) ENGINE= InnoDB AUTO_INCREMENT= 4 DEFAULT CHARSET=utf8mb4;

4.10、前端代码:


  
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title> </title>
  6. <script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"> </script>
  7. </head>
  8. <body>
  9. <h2>KingYiFan微信第三方登录测试之内嵌二维码 </h2>
  10. <div id="login_container"> </div>
  11. </body>
  12. <script>
  13. var obj = new WxLogin({
  14. self_redirect: false,
  15. id: "login_container",
  16. appid: "wxeaxxxxxxx41a91a",
  17. scope: "snsapi_login",
  18. redirect_uri: "http://20y85987b7.51mypc.cn",
  19. state: "",
  20. style: "black",
  21. href: "http://127.0.0.1:8848/yifantest/css/wechatLogin.css"
  22. });
  23. </script>
  24. </html>
  25. css样式:
  26. .impowerBox .qrcode {width: 200px;}
  27. .impowerBox .title {display: none;}
  28. .impowerBox .info {width: 200px;}
  29. .impowerBox .status {text-align: center;}

终、、以上就是web微信第三方登录 代码下载地址:https://download.csdn.net/download/weixin_39984161/12701680



转载:https://blog.csdn.net/weixin_39984161/article/details/107912921
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场