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

时间:2022-07-23
本文章向大家介绍一文搞定web微信第三方登录,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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

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

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

1.2、企业开发平台认证

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

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

1.4、配置回调地址(为了方便本地调试用的花生壳地址,也可以采用其他内网映射外网工具例如: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文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>cn.cnbuilder.wechat</groupId>
    <artifactId>pc-login</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>pc-login</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <!-- lib versions -->
        <WxJava.version>3.3.5.B</WxJava.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.1.21</version>
        </dependency>


        <!--添加fastjson依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>


        <!--注解做映射-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>


        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.8</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

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
     * <p>
     * 第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(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参数,参数会直接拼接在回调地址后面
     * <p>
     * 通过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一致
     * <br>  不一致,则直接返回这是一次非腾讯官方的回调请求。
     * 第二步:判断用户是否同意登录(查看是否有code)
     * <br>  不同意:则直接返回登录失败
     * 第三步:判断code是否有效,是否是腾讯返回的
     * <br>  是:获取信息
     * <br>  否:这是一次无效的登录请求
     *
     * @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<WeChatUserInfo> 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<String, Object> {

    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<String, Object> 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<WeChatUserInfo> {
}
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="cn.cnbuilder.wechat.webLogin.mapper.WechatUserInfoMapper">

</mapper>

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、前端代码:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
		<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
	</head>
	<body>
	 <h2>KingYiFan微信第三方登录测试之内嵌二维码</h2>
	 <div id="login_container"></div>
	</body>
	<script>
		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"
			});
	</script>
</html>
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)

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