天天看点

不懂第三方网站、App如何接入微信登录怎么办?这里我详解单点登录之第三方微信登录(建议收藏)

2021/9/3

文章目录

  • ​​一、前置准备​​
  • ​​二、微信登录流程分析​​
  • ​​第一步:请求code​​
  • ​​第二步:通过code获取access_token​​
  • ​​第三步:通过access_token调用获取用户信息​​
  • ​​三、接口核心代码详解​​
  • ​​1、编写生成微信二维码接口​​
  • ​​2、编写回调接口​​

一、前置准备

首先要去微信开放平台进行开发者资质认证

地址:​​https://open.weixin.qq.com/​​腾讯的东西你肯定也明白(白嫖不可能滴—>需要审核费)

当通过认证之后,需要记录下来三个核心参数

1、appid

2、app

3、redirecturl

二、微信登录流程分析

文档地址:​​https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html​​
不懂第三方网站、App如何接入微信登录怎么办?这里我详解单点登录之第三方微信登录(建议收藏)

第一步:请求code

这一步的作用就是发起微信授权登录请求,当用户确认后,微信会带着临时票据code重定向到第三方应用

用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数(这个redirect_uri就是你填写的开发域名)

redirect_uri?code=CODE&state=STATE

第二步:通过code获取access_token

通过code参数加上AppID和AppSecret等,通过API换取access_token;

不懂第三方网站、App如何接入微信登录怎么办?这里我详解单点登录之第三方微信登录(建议收藏)

{

“access_token”:“ACCESS_TOKEN”,

“expires_in”:7200,

“refresh_token”:“REFRESH_TOKEN”,

“openid”:“OPENID”,

“scope”:“SCOPE”,

“unionid”: “o6_bmasdasdsad6_2sgVt7hMZOPfL”

}

返回的是json数据,由此我们可以将其转换成map集合,然后get到其中的access_token的值(通过谷歌的Gson包,其他的都可以)

Gson gson = new Gson();
HashMap mapResult = gson.fromJson(result, HashMap.class);
String accessToken = (String) mapResult.get("access_token");
String openId = (String) mapResult.get("openid");      

第三步:通过access_token调用获取用户信息

这一步是通过凭证access_token去微信获取扫码用户的信息
不懂第三方网站、App如何接入微信登录怎么办?这里我详解单点登录之第三方微信登录(建议收藏)
不懂第三方网站、App如何接入微信登录怎么办?这里我详解单点登录之第三方微信登录(建议收藏)

也是通过转换为map格式,get到其中的value值

HashMap<String, Object> mapUserInfo = gson.fromJson(userInfo, HashMap.class);
String nickname = (String) mapUserInfo.get("nickname");    
String avatar = (String) mapUserInfo.get("headimgurl");      

三、接口核心代码详解

提示:以Java代码为例

注意:其中用到了一些工具类,例如HttpClientUtils用来进行远程调用,JwtUtils是使用jwt的工具类,还有一些其他的代码不再演示

1、编写生成微信二维码接口

既然要微信登录,那么肯定需要扫描二维码,没有二维码不就很扯犊子了吗。编写二维码接口,

不懂第三方网站、App如何接入微信登录怎么办?这里我详解单点登录之第三方微信登录(建议收藏)

注意下面的baseUrl,可以使用上方图片中拼接参数的方式,如果使用了这种方式,那么代码中的 format代码就可以省略

String qrUrl =String.format(baseUrl,ConstantVxUtil.VX_APP_ID, redirectUrl, “zsh”)
public String getQrConnect(HttpSession session) {
        // 微信开放平台授权baseUrl,这个baseUrl是固定不变的
//也可以拼接参数:https://open.../qrconnect?appid=你的appid &redirect_uri=.....
//如果用了拼接参数这种方法(和路径上加入参数类似),就不需要下面的String.format了
        String baseUrl = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +
                "&redirect_uri=%s" +
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";
        String redirectUrl = ConstantVxUtil.VX_REDIRECT_URL;
        try {
       // 使用utf-8方式编码
            redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String qrUrl = String.format(
                baseUrl,
                ConstantVxUtil.VX_APP_ID,
                redirectUrl,
                "zsh"
        );
        //重定向到二维码地址
        return "redirect:" + qrUrl;
    }      

2、编写回调接口

当用户扫码点击确认登录之后就会调用这个接口,在这个接口中通过先前获取的code与appid、appsecret向微信换取凭证access_token,最后通过access_token和appid去微信获取用户信息(也就是解析access_token,懂得单点登录的兄弟应该都明白)
@GetMapping("callback") //这个不要变
    public String callback(String code, String state, HttpSession session) {
    //下面两行代码是拼接参数,也可以使用类似于路径的那种方式 ?a=1&b=2
        String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                "?appid=%s" +
                "&secret=%s" +
                "&code=%s" +
                "&grant_type=authorization_code";
        String accessTokenUrl = String.format(baseAccessTokenUrl,
                ConstantVxUtil.VX_APP_ID,
                ConstantVxUtil.VX_APP_SECRET,
                code);
        String result = null;
        try {
            //向微信发出请求(参数:地址),获取access_token
            result = HttpClientUtils.get(accessTokenUrl);
        } catch (Exception e) {
            throw new CommonException(40026, "accessToken获取失败!");
        }
        //解析accessToken,将其转换为key-value形式
        Gson gson = new Gson();
        HashMap mapResult = gson.fromJson(result, HashMap.class);
        String accessToken = (String) mapResult.get("access_token");
        String openId = (String) mapResult.get("openid");
        User user= userInfoService.getUserByOpenId(openId);
        //判断是不是第一次使用微信登录,如果不是第一次,就不需要将信息存入数据库了
        //如果是第一次使用微信登录,那么数据库存储的有
        if (user == null) {
            String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                    "?access_token=%s" +
                    "&openid=%s";
            String userInfoUrl = String.format(baseUserInfoUrl,
                    accessToken,
                    openId);
            String userInfo = null;
            try {
                //根据token去vx获取用户信息
                userInfo = HttpClientUtils.get(userInfoUrl);
            } catch (Exception e) {
                throw new CommonException(20001, "获取信息失败");
            }
            //解析用户信息,将其转换为key-value形式,以便获取其中的value值
            HashMap<String, Object> mapUserInfo = gson.fromJson(userInfo, HashMap.class);
            String nickname = (String) mapUserInfo.get("nickname");
            String avatar = (String) mapUserInfo.get("headimgurl");
            //存入数据库
            user= new User();
            user.setNickname(nickname).setAvatar(avatar).setOpenid(openId);
            userService.save(user);
        }
        String token = JwtUtils.getToken(user.getId(), user.getNickname());
        return "redirect:http://localhost:8555?token="+token;
    }      

本文只讲述了两个接口代码,其他相关的代码(前端、工具类、xml等等)不再赘述。文章中的图片来源于微信开放平台的截图