首页 > 其他分享 >二维码关注公众号注册登录(登录,注册逻辑没写,请自行处理)

二维码关注公众号注册登录(登录,注册逻辑没写,请自行处理)

时间:2023-02-03 16:57:51浏览次数:46  
标签:String 登录 微信 token 二维码 自行处理 注册 import com

流程

生成推广二维码,上面带参数(场景值)。

用户扫描带场景值二维码时,可能推送以下两种事件:

​ 如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。(除了场景值,用户信息)

​ 如果用户已经关注公众号,在用户扫描后会自动进入会话,微信也会将带场景值扫描事件推送给开发者。

  • 相关文档

https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html

  • 后台接收接口

https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html

前提

  1. 准备好账号信息包含appId,appsecret。如果没有账号可以去申请一个沙盒https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

  2. 编写好代码去把后台接口配置信息配一下

    url: 你后台接收服务的地址,get和post请求得全部支持,前者验证,后者接收消息

    token: 拿来做验证的。微信服务器使用nonce来做sha1加密。

    ​ 注意:没有端口,拿个ngnix或者负载均衡配置一下(微信服务器只支持443和80端口)。这只是最简单的后台接收微信消息(扫码登录,发消息,取消关注等等)

依赖

        <!--hu-tool工具-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.11</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.24</version>
        </dependency>

        <!--编解码-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>

        <!--解析xml-->
        <dependency>
            <groupId>org.dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.9</version>
        </dependency>

代码

  • 控制器
package com.test.wxproduction.controller;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/login")
public class LoginController {
    // appId\appSecret 实际生产中应该配置到数据库
    private static String appId = "wx017275cd59d7000";
    private static String appSecret = "0eac664b6743decf9af7f5cca4810000";
    //微信后台设置的token(用来做接口验证)
    private static String TOKEN = "wx017275cd59d70000";

    /**
     * @Description : 生成二维码url
     * @Return : java.lang.String
     * @Author : 郝子樑
     * @Date : 2023-02-03 14:00
    */
    @GetMapping("/codeUrl")
    public String codeUrl(){
        //获取access_token
        //先拿着自己的appid和appSecret 去查询在微信后台的token
        String temp = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
        temp = String.format(temp,appId,appSecret);
        String s = HttpUtil.get(temp);
        //提取token
        JSONObject bb =  JSON.parseObject(s);
        String token = bb.getString("access_token");
        
        //获取到token后问微信后台要求生成一个ticket(这个是作为二维码的标识id)
        HashMap<String,Object> postBody = new HashMap<>();
        //拼接参数
        postBody.put("expire_seconds",604800);
        postBody.put("action_name","QR_SCENE");
        HashMap<String,Object> info = new HashMap<>();
        HashMap<String,Object> scene = new HashMap<>();
        scene.put("scene_id",123);
        info.put("scene",scene);
        postBody.put("action_info",info);

        String jsonString = JSON.toJSONString(postBody);
        //说明
//        expire_seconds	该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为60秒。
//        action_name	二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值
//        action_info	二维码详细信息
//        scene_id	场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)
//        scene_str	场景值ID(字符串形式的ID),字符串类型,长度限制为1到64
        String res = HttpUtil.post("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+token, jsonString);
        //JSON中可以取到ticket信息,拿着去换二维码
        //拿着ticket就可以直接拼接个url,指向二维码图片
        JSONObject object =  JSON.parseObject(res);
        System.out.println(res);
        String ticket = object.getString("ticket");

        //二维码地址
        String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="+ticket;
        return url;
    }

    /**
     * @Description : 微信后台初次设置时要验证接口是否连通,这里按照官方文档写一下验证规则就好
     * @Params : [req, resp]
     * @Return : java.lang.String
     * @Author : 郝子樑
     * @Date : 2023-02-03 16:30
    */
    @GetMapping("/notify")
    public String echo(HttpServletRequest req, HttpServletResponse resp) {
        System.out.println("接收到消息了!!!!!!!!!!!");
        // 1.获取微信传入的4个参数
        String signature = req.getParameter("signature");
        String timestamp = req.getParameter("timestamp");
        String nonce = req.getParameter("nonce");
        String echostr = req.getParameter("echostr");
        // 2.用timestamp, nonce, signature进行校验
        boolean result = check(timestamp, nonce, signature);
        if (result) {
            // 3.校验成功返回echostr
            return echostr;
        }
        return "error!";
    }

    
    /**
     * @Description : 微信后台拿来接收消息的接口,设置时发送get,后续就是post,请求中带有xml文件,从xml文件中读取内容。
     * @Params : [response, request]
     * @Return : void
     * @Author : 郝子樑
     * @Date : 2023-02-03 16:32
    */
    
    @PostMapping("/notify")
    public void handleMsgIn(HttpServletResponse response, HttpServletRequest request) throws Exception {
        // 从request中取得微信通知的消息
        Map<String, String> msgMap = MessageUtil.parseXml(request);
        System.out.println("微信收到的消息:"+msgMap);
    }

    public static boolean check(String timestamp, String nonce, String signature) {
        // 1.按字典序对TOKEN, timestamp和nonce排序
        String[] arr = new String[]{TOKEN,timestamp,nonce};
        Arrays.sort(arr);
        // 2.将3个参数拼成一个字符串进行sha1加密
        String str = arr[0]+arr[1]+arr[2];
        // 3.用commons-codec包中的工具类进行sha1加密
        str = DigestUtils.sha1Hex(str);
        // 4.将加密后的字符串和signature比较
        System.out.println(signature);
        return str.equalsIgnoreCase(signature);
    }
}
  • 工具类
package com.test.wxproduction.controller;

import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class MessageUtil {
    /**
     * 解析微信发来的请求(XML)
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap<String, String>();

        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点

        @SuppressWarnings("unchecked")
        List<Element> elementList = root.elements();

        // 遍历所有子节点
        for (Element e : elementList)
            map.put(e.getName(), e.getText());

        // 释放资源
        inputStream.close();
        inputStream = null;
        return map;
    }

    /**
     * 扩展xstream,使其支持CDATA块
     *
     */
    private static XStream xstream = new XStream(new XppDriver() {
        @Override
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out) {
                // 对所有xml节点的转换都增加CDATA标记
                boolean cdata = true;
                @Override
                protected void writeText(QuickWriter writer, String text) {
                    if (cdata) {
                        writer.write("<![CDATA[");
                        writer.write(text);
                        writer.write("]]>");
                    } else {
                        writer.write(text);
                    }
                }
            };
        }
    });
}

标签:String,登录,微信,token,二维码,自行处理,注册,import,com
From: https://www.cnblogs.com/beamsoflight/p/17089802.html

相关文章

  • JupyterHub(TLJH)安装卸载, 以及配置GitLab的OAuth登录和开启HTTPS
    介绍JupyterHub是可供多用户使用的JupyterNotebook安装JupyterHub分两个版本,ZerotoJupyterHubwithK8s和TheLittlestJupyterHub前者可以使用K8s集群进行部署,......
  • 如何注册 ChatGPT Plus:稳定不掉线升级版 ChatGPT
    ChatGPT自从2022年11月30号发布以来已经形成了AI热浪席卷全球。许多人已经离不开ChatGPT。然而免费版本的ChatGPT却常常因为过高的负载导致无法正常访问。好消息是,......
  • kubernetes-dashboard 实现 http 访问以及免 token 登录
    目录下载官方yaml文件修改yaml文件修改service端口修改clusterrolebinding修改deployment内容修改探针检测修改镜像拉取策略修改容器端口关闭token登录增加ing......
  • 注册外贸公司需要注意的问题
    关于注册海外公司需要注意事项,米贸搜以美国为例,整理以下信息,希望可以帮助到你一、注册美国公司注意事项:1、拟定要注册的美国公司名称三个(英文),核名如无重复则可使用;2、美国公......
  • 单点登录(SSO)的设计与实现
    本文转载自 https://ken.io/note/sso-design-implement 一、前言1、SSO说明SSO英文全称SingleSignOn,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访......
  • 登录功能代码实现
    登录功能_代码实现publicclassLoginServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponserespo......
  • 小程序扫码登录网页端原理
    目录一、问题引入二、几个难题1.网页端是怎么知道哪个用户扫描的二维码?2.小程序扫码,扫出来的是什么东西?3.小程序扫到二维码以后,做了什么事情,怎么和网页端通讯的......
  • 通过注册表设置控制台的属性
    想更改控制台的背景颜色和前景色,通过打开一个新的cmd,右键点击标题栏,属性,点击颜色选项卡,设置屏幕背景和屏幕文字。如下:  点击确定后,新启动一个cmd,显示的就是新的颜色......
  • 用小程序来实现扫码登录
    小程序扫码登录的优点不需要企业资质,个人用户就可以注册小程序;不需要认证,每年可以省300元;打通小程序端的用户数据,可以让PC网站往移动端引流,用户不流失;流程......
  • Dubbo 中 Zookeeper 注册中心原理分析
    vivo互联网服务器团队-LiWanghong本文通过分析Dubbo中ZooKeeper注册中心的实现ZooKeeperResitry的继承体系结构,自顶向下分析了AbstractRegistry(提供了服务数据的本地......