一文搞定web微信第三方登录 您所在的位置:网站首页 手机网页微信 一文搞定web微信第三方登录

一文搞定web微信第三方登录

2024-01-19 02:45| 来源: 网络整理| 查看: 265

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

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

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

filefile

1.2、企业开发平台认证

filefile

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

filefile

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

filefile

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

filefile

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

微信文档登录流程:

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

腾讯官方提供的流程图:

filefile

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

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

filefile

3.1、第一步请求code:

filefile

封装获取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、代码演示:

filefile

service层拼接url参数:

filefile

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

filefile

访问获取code地址:

filefile

扫码登录:

filefile

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

filefile

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

controller层:

filefile

service层:

filefile

postman请求获取用户信息:

filefile

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

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

filefile

第一步:查阅官方文档:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

filefile

第二步:写前端代码:

filefile

后续步骤和方案1一致:

登录:

filefile

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

filefile

拿着code获取用户信息:

filefile

四、分享代码:

filefile

4.1、pom文件:

4.0.0 org.springframework.boot spring-boot-starter-parent 2.3.2.RELEASE cn.cnbuilder.wechat pc-login 0.0.1-SNAPSHOT pc-login Demo project for Spring Boot 1.8 3.3.5.B org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter mysql mysql-connector-java 5.1.46 com.baomidou mybatis-plus-boot-starter 3.0.7.1 org.projectlombok lombok true cn.hutool hutool-all 4.1.21 com.alibaba fastjson 1.2.28 org.springframework.boot spring-boot-starter-data-jpa org.apache.commons commons-lang3 3.8 org.springframework.boot spring-boot-maven-plugin

4.2、controller:

index controller package cn.cnbuilder.wechat.webLogin.controller; import cn.cnbuilder.wechat.webLogin.entity.R; import cn.cnbuilder.wechat.webLogin.service.WechatWebLoginService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; /** * 首页 * create on 2020/08/07 by kingyifan */ @RestController public class IndexController { @GetMapping(value = "/") public String getCreatCodeUrl() { return "wechat之web第三方登录工程"; } } WechatWebLoginController: package cn.cnbuilder.wechat.webLogin.controller; import cn.cnbuilder.wechat.webLogin.service.WechatWebLoginService; import cn.cnbuilder.wechat.webLogin.entity.R; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; /** * wechat之web端第三方登录 * create on 2020/08/07 by kingyifan */ @RestController @RequestMapping("/wechat") public class WechatWebLoginController { @Autowired private WechatWebLoginService wechatWebLoginService; /** * 获取生成用户点击之后能获取code的接口 * 第一步:请求CODE *

* 第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login), * 则可以通过在PC端打开以下链接:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect * 若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。 * 以上摘自-腾讯官方文档 :https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html * * @param request 获取HttpServletRequest中session存放STATE * STATE 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 * @return URL 微信登录请求地址 */ @GetMapping(value = "/getCreatCodeUrl") @ResponseBody public R getCreatCodeUrl(HttpServletRequest request) { String getCodeUrl = wechatWebLoginService.getCreatCodeUrl(request); return R.ok().data(getCodeUrl); } /** * 通过getCreatCodeUrl方法并且用户授权之后前端页面会拿到code参数,参数会直接拼接在回调地址后面 *

* 通过code获取access_token、openid、unionid(当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。) * * @param request * @return */ @GetMapping(value = "/getUserInfoByCode") @ResponseBody public R getUserInfoByCode(HttpServletRequest request) { //true:state是否存放session return wechatWebLoginService.getInfoByCode(request); } }

4.3、service:

service接口: package cn.cnbuilder.wechat.webLogin.service; import cn.cnbuilder.wechat.webLogin.entity.R; import javax.servlet.http.HttpServletRequest; import java.util.Map; public interface WechatWebLoginService { String getCreatCodeUrl(HttpServletRequest request); R getInfoByCode(HttpServletRequest request ); } serviceImpl: package cn.cnbuilder.wechat.webLogin.service.impl; import cn.cnbuilder.wechat.webLogin.entity.R; import cn.cnbuilder.wechat.webLogin.entity.WeChatUserInfo; import cn.cnbuilder.wechat.webLogin.entity.WechatBaseInfo; import cn.cnbuilder.wechat.webLogin.mapper.WechatUserInfoMapper; import cn.cnbuilder.wechat.webLogin.service.WechatWebLoginService; import cn.cnbuilder.wechat.webLogin.utils.WechatWebLoginUtil; import cn.hutool.core.util.RandomUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Service public class WechatWebLoginServiceImpl implements WechatWebLoginService { @Autowired private WechatUserInfoMapper wechatUserInfoMapper; @Override public String getCreatCodeUrl(HttpServletRequest request) { //state参数:用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 //第一步生成随机的state参数 该参数可用于防止csrf攻击(跨站请求伪造攻击) String state = RandomUtil.randomString(8); //第二步存放session request.getSession().setAttribute("state", state); //获取用户点击url可以生成code的链接 String getCodeUrl = WechatWebLoginUtil.getCodeUrl(state); return getCodeUrl; } /** * 根据code获取信息 * 第一步:判断state是否和我们存放的state一致 * 不一致,则直接返回这是一次非腾讯官方的回调请求。 * 第二步:判断用户是否同意登录(查看是否有code) * 不同意:则直接返回登录失败 * 第三步:判断code是否有效,是否是腾讯返回的 * 是:获取信息 * 否:这是一次无效的登录请求 * * @param request */ @Override public R getInfoByCode(HttpServletRequest request) { String isSetState = request.getParameter("state"); //是否存放State if (isSetState != null && StringUtils.isNotEmpty(isSetState)) { /** * 第一步 * 查看state是否和我们存放的一致; */ //微信给的state String wstate = request.getParameter("state"); //session中的state Object sstate = request.getSession().getAttribute("state"); if (StringUtils.isEmpty(sstate.toString()) || !sstate.equals(wstate)) { return R.error(500, "恶意请求"); } } /** * 第二步查看用户是否授权: * 用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数 * redirect_uri ? code = CODE & state = STATE * 若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数 以上摘自微信官方文檔:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html */ //获取腾讯给的code String code = request.getParameter("code"); //判断是否是空的。 if (StringUtils.isBlank(code) || StringUtils.isEmpty(code)) { return R.error(500, "code为空!"); } //调用微信通过code获取access_token接口 WechatBaseInfo wechatBaseInfo = WechatWebLoginUtil.getBaseInfoByCode(code); if (wechatBaseInfo.getErrcode() != null) { return R.error(500, wechatBaseInfo.getErrmsg()); } //获取到基础开发信息之后,判断用户信息在db是否完整 QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.eq("openid", wechatBaseInfo.getOpenid()); WeChatUserInfo dWeChatUserInfo = wechatUserInfoMapper.selectOne(queryWrapper); //用户信息不存在 if (dWeChatUserInfo != null) { //如果db存在则直接返回,如果怕用户更改了资料也可以重新走一下获取用户信息接口 return R.ok().data(dWeChatUserInfo); } //获取基础信息获取用户信息 WeChatUserInfo wechatUserInfo = WechatWebLoginUtil.getUserInfoByOpenid(wechatBaseInfo); if (wechatUserInfo == null) { return R.error(500, "用户信息获取失败!"); } wechatUserInfoMapper.insert(wechatUserInfo); return R.ok().data(wechatUserInfo); } }

4.4、工具类:

package cn.cnbuilder.wechat.webLogin.utils; import cn.cnbuilder.wechat.webLogin.entity.WeChatUserInfo; import cn.cnbuilder.wechat.webLogin.entity.WechatBaseInfo; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import org.apache.commons.lang3.StringUtils; /** * 微信第三方web登录工具类 * create on 2020.08.07 by kingyifan */ public class WechatWebLoginUtil { //微信开放平台申请pc应用开发密钥 可以后期弄到配置文件动态获取 public static String APPID = "xxxxxxxxx"; public static String APPSECRET = "xxxxxxxxx"; //-------------------------------------微信第三方登录信息------------------------------------------------// //获取codeurl下面是固定的 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"; //微信回调地址(这个地址可以说是前端页面,这个地址腾讯回调过来会在后面拼code参数) public static String REDIRECTURI = "http://20y85987b7.51mypc.cn/"; //应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login public static String SCOPE = "snsapi_login"; // 获取access_token 通过code获取access_token public static String ACCESSTOKENURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code"; //根据openid获取用户信息接口地址 public static String USERINFOURL = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID"; /** * 拼接获取code的:接口地址 * * @param state 随机数 防止csrf攻击(跨站请求伪造攻击) * @return */ public static String getCodeUrl(String state) { //替换appId、回调url 以及state参数 return GETCODEURL.replace("APPID", APPID).replace("REDIRECT_URI", REDIRECTURI).replace("SCOPE", SCOPE).replace("STATE", state); } /** * 根据code获取用户基础开发信息、AccessToken、openId、unionId、refreshToken * * @param code 临时授权凭证 * @return */ public static WechatBaseInfo getBaseInfoByCode(String code) { //基础信息实体类 WechatBaseInfo wechatBaseInfo = new WechatBaseInfo(); //拼接获取access_token的请求地址 String accessTokenUrl = ACCESSTOKENURL.replace("APPID", APPID).replace("SECRET", APPSECRET).replace("CODE", code); //發送请求获取基础开发信息 String getResponseInfo = HttpUtil.get(accessTokenUrl); if (StringUtils.isEmpty(getResponseInfo)) { wechatBaseInfo.setErrcode(-1); wechatBaseInfo.setErrmsg("错误请求"); return wechatBaseInfo; } //把请求结果转成json对象 JSONObject reObject = JSONUtil.parseObj(getResponseInfo); //判断是否有异常 比如code失效。。。。 if (reObject.getInt("errcode") != null) { /** * 错误返回样例: * { * "errcode":40029, * "errmsg":"invalid code" * } */ wechatBaseInfo.setErrcode(reObject.getInt("errcode")); wechatBaseInfo.setErrmsg(reObject.getStr("errmsg")); return wechatBaseInfo; } else { /** *正确的返回: * { * "access_token":"ACCESS_TOKEN", * "expires_in":7200, * "refresh_token":"REFRESH_TOKEN", * "openid":"OPENID", * "scope":"SCOPE", * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" * } */ //接口调用凭证 wechatBaseInfo.setAccess_token(reObject.getStr("access_token")); //access_token接口调用凭证超时时间,单位(秒) wechatBaseInfo.setExpires_in(reObject.getStr("expires_in")); //用户刷新access_token wechatBaseInfo.setRefresh_token(reObject.getStr("refresh_token")); // 授权用户唯一标识 wechatBaseInfo.setOpenid(reObject.getStr("openid")); //用户授权的作用域,使用逗号(,)分隔 wechatBaseInfo.setScope(reObject.getStr("scope")); // unionid 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。 wechatBaseInfo.setUnionid(reObject.getStr("unionid")); return wechatBaseInfo; } } /** * 根据基础开发信息获取用户信息 * * @param wechatBaseInfo * @return */ public static WeChatUserInfo getUserInfoByOpenid(WechatBaseInfo wechatBaseInfo) { WeChatUserInfo weChatUserInfo = new WeChatUserInfo(); //拼接获取userinfo的请求地址 String userInfoUrl = USERINFOURL.replace("ACCESS_TOKEN", wechatBaseInfo.getAccess_token()).replace("OPENID", wechatBaseInfo.getOpenid()); //發送请求获取用户信息 String getResponseInfo = HttpUtil.get(userInfoUrl); if (StringUtils.isEmpty(getResponseInfo)) { weChatUserInfo.setErrcode(-1); weChatUserInfo.setErrmsg("错误请求"); return weChatUserInfo; } //把请求结果转成json对象 JSONObject reObject = JSONUtil.parseObj(getResponseInfo); //判断是否有异常 比如无效的openId if (reObject.getInt("errcode") != null) { /** * 错误的Json返回示例: * { * "errcode":40003, * "errmsg":"invalid openid" * } */ weChatUserInfo.setErrcode(reObject.getInt("errcode")); weChatUserInfo.setErrmsg(reObject.getStr("errmsg")); return weChatUserInfo; } else { //普通用户的标识,对当前开发者帐号唯一 weChatUserInfo.setOpenid(reObject.getStr("openid")); //普通用户昵称 weChatUserInfo.setNickname(reObject.getStr("nickname")); //普通用户性别,1为男性,2为女性 weChatUserInfo.setSex(reObject.getInt("sex")); // 普通用户个人资料填写的省份 weChatUserInfo.setProvince(reObject.getStr("province")); //普通用户个人资料填写的城市 weChatUserInfo.setCity(reObject.getStr("city")); //国家,如中国为CN weChatUserInfo.setCountry(reObject.getStr("country")); //TODO 请注意,在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况。 这里需要下载用户头像然后保存到自己的服务器 这一步省略。。。 //用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 weChatUserInfo.setHeadimgurl(reObject.getStr("headimgurl")); // 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) weChatUserInfo.setPrivilege(reObject.getJSONArray("privilege").toString()); //用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 weChatUserInfo.setUnionid(reObject.getStr("unionid")); return weChatUserInfo; } } }

4.5、实体类:

R:统一返回实体: package cn.cnbuilder.wechat.webLogin.entity; import java.util.HashMap; import java.util.Map; public class R extends HashMap { private static final long serialVersionUID = -8713837118340960775L; public R() { put("code", 200); put("msg", "success"); } public static R error() { return error(500, "未知异常,请联系管理员"); } public static R error(String msg) { return error(500, msg); } public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map map) { R r = new R(); r.putAll(map); return r; } public static R ok() { return new R(); } public R message(String message) { this.put("message", message); return this; } public R data(Object data) { this.put("data", data); return this; } @Override public R put(String key, Object value) { super.put(key, value); return this; } public String getMessage() { return String.valueOf(get("message")); } public Object getData() { return get("data"); } public Integer getCode() { return (Integer) get("code"); } } 微信第三方登录基础开发信息: package cn.cnbuilder.wechat.webLogin.entity; import lombok.Data; /** * 微信web登录基础开发信息 * 文档地址:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html */ @Data public class WechatBaseInfo { /** * 接口调用凭证 */ private String access_token; /** * access_token接口调用凭证超时时间,单位(秒) */ private String expires_in; /** * 用户刷新access_token */ private String refresh_token; /** * 授权用户唯一标识 */ private String openid; /** * 用户授权的作用域,使用逗号(,)分隔 */ private String scope; /** * 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段 */ private String unionid; /** * 错误编码 */ private Integer errcode; /** * 错误信息 */ private String errmsg; } 用户信息实体: package cn.cnbuilder.wechat.webLogin.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import javax.persistence.Table; import javax.persistence.Transient; import javax.persistence.criteria.CriteriaBuilder; @Data @TableName("wechat_userinfo") public class WeChatUserInfo { /** * 普通用户的标识,对当前开发者帐号唯一 */ private String openid; /** * 普通用户昵称 */ private String nickname; /** * 普通用户性别,1为男性,2为女性 */ private Integer sex; /** * 普通用户个人资料填写的省份 */ private String province; /** * 普通用户个人资料填写的城市 */ private String city; /** * 国家,如中国为CN */ private String country; /** * 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 */ private String headimgurl; /** * 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) */ private String privilege; /** * 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 */ private String unionid; /** * 错误编码 */ @TableField(exist = false) private Integer errcode; /** * 错误信息 */ @TableField(exist = false) private String errmsg; }

mapper文件:

package cn.cnbuilder.wechat.webLogin.mapper; import cn.cnbuilder.wechat.webLogin.entity.WeChatUserInfo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @Mapper public interface WechatUserInfoMapper extends BaseMapper { } xml文件:

4.6、启动类:

package cn.cnbuilder.wechat.webLogin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PcLoginApplication { public static void main(String[] args) { SpringApplication.run(PcLoginApplication.class, args); } }

4.7、配置文件:

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

4.8、sql:

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

4.9、前端代码:

KingYiFan微信第三方登录测试之内嵌二维码 var obj = new WxLogin({ self_redirect:false, id:"login_container", appid: "wxeaxxxxxxx41a91a", scope: "snsapi_login", redirect_uri: "http://20y85987b7.51mypc.cn", state: "", style: "black", href: "http://127.0.0.1:8848/yifantest/css/wechatLogin.css" }); css样式: .impowerBox .qrcode {width: 200px;} .impowerBox .title {display: none;} .impowerBox .info {width: 200px;} .impowerBox .status {text-align: center;}

终、、以上就是web微信第三方登录

网站名称:猿码优创 网站地址:http://blog.cnbuilder.cn 网站描述:年少是你未醒的梦话,风华是燃烬的彼岸花。 网站Logo/头像: [头像地址](https://blog.cnbuilder.cn/upload/2018/7/avatar20180720144536200.jpg)

欢迎关注猿码优创(联系小优优进内部群哦,新鲜技术优先更新):



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有