Connexion tierce : connexion par code de numérisation WeChat


Les amis qui ont diverses questions peuvent se référer aux documents officiels pour étudier en détail les documents de développement de WeChat.Cette fois, nous présenterons la connexion par code scan WeChat qui ne sépare pas le front-end et le back-end.

Processus de développement de la connexion WeChat :

  1. Demander un accès à WeChat
  2. Générer le code QR de connexion
  3. L'utilisateur scanne le code et autorise
  4. Appeler la méthode de rappel
  5. Obtenez des informations sur l'utilisateur via le code et amenez-les sur la page pour les afficher

Organigramme officiel :
insérer la description de l'image ici

1. Demandez l'accès à WeChat :

Tout d'abord, je voudrais rappeler à tout le monde : il est très difficile de demander un accès à WeChat. En raison des besoins commerciaux de l'entreprise, j'utilise l'application de l'entreprise. Je ne me suis pas encore appliqué.

Accédez d’abord à la plateforme ouverte WeChat https://open.weixin.qq.com

insérer la description de l'image ici
Demander une application sur un site Web (ne peut être utilisé qu'après approbation)

insérer la description de l'image ici
Note:

  1. appid et appSecret sont les informations d'identification pour appeler l'interface WeChat
  2. Domaine de rappel d'autorisation : l'adresse du code QR générée en appelant l'interface WeChat. Une fois que l'utilisateur a scanné le code et l'a autorisé, l'utilisateur sera redirigé vers l'adresse de rappel.
  3. Étant donné que le test est effectué sur localhost, WeChat tiers ne pourra pas sauter si l'adresse de rappel est localhost. La raison est que le réseau externe ne peut pas accéder à la zone locale. Que dois-je faire ? Solution : utilisez ensuite la pénétration de l'intranet ngrok pour mapper le service du projet local au réseau public, de sorte que l'adresse de rappel renseignée lors du test soit le nom de domaine d'accès. lors de la pénétration de l'intranet.
  4. Si vous ne connaissez pas la pénétration intranet, je vous suggère de jeter d'abord un œil à l'utilisation de la pénétration intranet Sunny-Ngrok .

insérer la description de l'image ici

Si vous ne connaissez pas la pénétration intranet, je vous suggère de jeter d'abord un œil à l'utilisation de la pénétration intranet Sunny-Ngrok .

Démarrez le client de pénétration intranet Sunny-Ngrok et mappez d'abord le service local au réseau public.

insérer la description de l'image ici

2. Configuration de l'environnement du projet :

Commençons officiellement la partie code, créons un projet SpringBoot et importons le package Jar requis :
Environnement : 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>

Fichier Yaml :
ces quatre paramètres étant obligatoires, ils sont configurés directement dans le fichier yaml. Lorsqu'ils sont utilisés, ils peuvent être introduits directement dans la classe via l'annotation @Value.

  1. appid:
  2. secret d'application :
  3. portée : snsapi_login
  4. rappeler:
server:
  port: 80

spring:
  thymeleaf:
    prefix: classpath:/templates/
    suffix: .html
  mvc:
    static-path-pattern: classpath:/static/

wechat:
  #微信接口的AppID:
  appid: 
  #微信接口的AppSecret:
  appsecret: 
  #应用授权作用域(网站应用目前的固定写法就是snsapi_login)
  scope: snsapi_login
  #扫码之后的回调地址:
  callBack: http://wechatlogin.free.idcfengye.com/callBack

Une classe d'outils HttpRequestUtils est nécessaire ici pour lancer des requêtes http. Vous pouvez copier le code directement et utiliser

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;

/**
 * @author: libo
 * @date: 2020/11/21  20:49
 * @motto: 即使再小的帆也能远航
 */
public class HttpRequestUtils {
    
    

    private static CloseableHttpClient httpClient;

    static {
    
    
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(100);
        cm.setDefaultMaxPerRoute(20);
        cm.setDefaultMaxPerRoute(50);
        httpClient = HttpClients.custom().setConnectionManager(cm).build();
    }

    public static String httpGet(String url) {
    
    
        CloseableHttpResponse response = null;
        BufferedReader in = null;
        String result = "";
        try {
    
    
            HttpGet httpGet = new HttpGet(url);
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
            httpGet.setConfig(requestConfig);
            httpGet.setConfig(requestConfig);
            httpGet.addHeader("Content-type", "application/json; charset=utf-8");
            httpGet.setHeader("Accept", "application/json");
            response = httpClient.execute(httpGet);
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
    
    
                sb.append(line + NL);
            }
            in.close();
            result = sb.toString();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            try {
    
    
                if (null != response) {
    
    
                    response.close();
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        return result;
    }
}

3. Interface du contrôleur principal :

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;

/**
 * @author: libo
 * @date: 2020/11/21  21:32
 * @motto: 即使再小的帆也能远航
 */
@Controller
@CrossOrigin
@SuppressWarnings("unchecked")
public class weChatController {
    
    

    @Value(value = "${wechat.appid}")
    private String appid;

    @Value(value = "${wechat.appsecret}")
    private String appsecret;

    @Value(value = "${wechat.scope}")
    private String scope;

    @Value(value = "${wechat.callback}")
    private String callBack;


    /*生产二维码链接进行扫码登录*/
    @RequestMapping("/login")
    public String index(Model model) throws Exception {
    
    

        String oauthUrl = "https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
        String redirect_uri = URLEncoder.encode(callBack, "utf-8");
        oauthUrl = oauthUrl.replace("APPID", appid).replace("REDIRECT_URI", redirect_uri).replace("SCOPE", scope);
        model.addAttribute("oauthUrl", oauthUrl);

        return "login";
    }


    /*生成自定义二维码*/
    @RequestMapping("/custom")
    public String custom(Model model) throws UnsupportedEncodingException {
    
    

        String redirect_uri = URLEncoder.encode(callBack, "utf-8");

        model.addAttribute("appid", appid);
        model.addAttribute("scope", scope);
        model.addAttribute("redirect_uri", redirect_uri);

        return "custom";
    }


    /*回调方法*/
    @RequestMapping("/callBack")
    public String callBack(String code,Map<String,Object> map) {
    
    

        //1.通过code获取access_token
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        url = url.replace("APPID", appid).replace("SECRET", appsecret).replace("CODE", code);
        String tokenInfoStr = HttpRequestUtils.httpGet(url);

        JSONObject tokenInfoObject = new JSONObject(tokenInfoStr);

        //2.通过access_token和openid获取用户信息
        String userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
        userInfoUrl = userInfoUrl.replace("ACCESS_TOKEN", tokenInfoObject.getString("access_token")).replace("OPENID", tokenInfoObject.getString("openid"));
        String userInfoStr = HttpRequestUtils.httpGet(userInfoUrl);

        map.put("token", tokenInfoStr);

        /*转为JSON*/
        JSONObject user = new JSONObject(userInfoStr);

        /*只获取openid并返回,openid是微信用户的唯一标识,userInfoStr里面有用户的全部信息*/
        String openid = user.getString("openid");
        map.put("openid", openid);

        /*获取用户头像url*/
        String headimgurl = user.getString("headimgurl");
        map.put("headimgurl", headimgurl);

        /*获取用户昵称*/
        String nickname = user.getString("nickname");
        map.put("nickname", nickname);

        /*获取用户性别*/
        int sex = user.getInt("sex");
        map.put("sex", sex);

        /*获取用户国家*/
        String country = user.getString("country");
        map.put("country", country);

        /*获取用户省份*/
        String province = user.getString("province");
        map.put("province", province);

        /*获取用户城市*/
        String city = user.getString("city");
        map.put("city", city);

        return "callBack";
    }

}

4.Code de la page HTML :

1. Cliquez pour générer la page de code QR : j'ai intégré une image du logo WeChat ici, cliquez sur l'étiquette pour accéder à weChatLogin.htmlinsérer la description de l'image ici

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

2. Après avoir appelé la méthode, revenez à la page d'informations utilisateur callBack.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>授权结果页</title>
</head>
<body>

        <h2>用戶,授权成功!</h2><br>
        <h3>通过code获取access_token 结果:</h3>
        <p th:text="${token}"></p>

        <h3>通过access_token获取用户信息 结果:</h3>
        头像:<img th:src="${headimgurl}" alt="用户头像"><br/>
        openid:<span th:text="${openid}"></span><br/>
        昵称:<span th:text="${nickname}"></span><br/>
        性别:<span th:text="${sex}"></span><br/>
        国家:<span th:text="${country}"></span><br/>
        省份:<span th:text="${province}"></span><br/>
        城市:<span th:text="${city}"></span>

</body>
</html>

3. Intégrer (code QR personnalisé) custom.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>内嵌(自定义二维码)</title>
</head>
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
<body>

<center><div id="login_container"></div></center>
<script th:inline="javascript">
    var obj = new WxLogin({
    
    
        self_redirect:true,
        id:"login_container",
        appid: [[${
    
    appid}]],
        scope: [[${
    
    scope}]],
        redirect_uri: [[${
    
    redirect_uri}]],
        state: "",
        style: "",
        href: ""
    });
</script>
</body>
</html>

5. Résultats des tests :

Utilisez le nom de domaine pénétré par l'intranet pour accéder à l'interface, car il a été mappé au projet local sur le réseau public.

  1. Accédez à l'interface de connexion et cliquez sur l'icône du logo
    insérer la description de l'image ici

  2. Test du code de numérisation

insérer la description de l'image ici

  1. Après autorisation, appelez la méthode de rappel pour obtenir les informations de l'utilisateur et les afficher sur la page.Remarque
    : openid est l'identifiant unique de l'utilisateur WeChat.

insérer la description de l'image ici

6. Explication supplémentaire :

À ce stade, il suffit presque de se connecter à SpringBoot via WeChat sans séparer les extrémités avant et arrière. Je voudrais vous dire quoi faire si les extrémités avant et arrière sont séparées ?

1. L'adresse de rappel est généralement la page d'accueil du site Web, par exemple : www.abc.com
2. Le bouton frontal génère un code QR via l'application et l'adresse de rappel
3. Une fois que l'utilisateur a scanné le code pour autorisation, le L'interface WeChat sera redirigée via l'adresse de rappel de la page d'accueil www.abc.com. Il y aura un paramètre nommé code
4. À ce stade, une fois que le front-end a le code, il est transmis à la méthode d'interface back-end et le back-end obtient les informations utilisateur via le code. Retour au début

Résumé en une phrase : 1. Générez un code QR sur la page d'accueil de www.adc.com, 2. Scannez le code pour autoriser la connexion, 3. Utilisez les paramètres du code pour obtenir des informations sur l'utilisateur.

Il n’y a presque rien qui ne puisse être simplifié si nous y réfléchissons à deux fois.

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45377770/article/details/109901312
conseillé
Classement