网站用微信扫描二维码登录

15 篇文章 1 订阅
12 篇文章 0 订阅

网站实现扫描二维码关注微信公众号,自动登陆网站并获取其信息

生成带参数的二维码-微信开发文档

 

需求

     网站实现扫描二维码关注微信公众号,如果已经关注公众号就自动登陆网站并获取其微信昵称,头像等信息,如果用户未关注就等用户关注公众号后自动登陆网站

     --如果用户已关注公众号,网站端直接自动登陆,如果没有关注,就等用户关注公众号之后网站端自动登陆

     (目前已经完成了这个功能,示例网址:http://www.bid-data.com/ 爱招标——免费实时标讯推送平台,为企业负责人及商务人员即时掌控招标动态、中标检索、竞争对手中标项目分析等服务平台。)

   做微信扫码登陆,生成二维码必须是微信公众号中绑定的域这个域名,网站生成不了二维码(网站与微信服务器不是同一个域名) ,而是调用微信系统的接口获取二维码,用户扫码后也是请求微信服务器 

   

实现思路

   1,微信的系统,提供生成带参数的二维码的接口,这个参数就是唯一值(场景值)
   2,网站调用微信系统,获取生成的二维码图片
   3,用户扫码会直接调用微信服务器,将用户访问微信服务器的信息记录到redis,key就是唯一值(场景值)
   4,网站端做轮训去查询redis中是否有这个唯一值的数据,如果有就获取用户信息登录,没有就五秒一次轮训,登录后就不在做轮训(从二维码弹出之后开始做轮训,关闭二维码后停止轮训)

   5,这里的唯一值是可以自己定义的,我用的是截取了几位的时间戳 

 

实现步骤

(1)微信端:写一个获取带参数的临时二维码接口。

// 临时二维码 
    private final static String QR_SCENE = "QR_SCENE";  
    // 永久二维码  
    private final static String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";  
    // 永久二维码(字符串)  
    private final static String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";   
    // 创建二维码  
    private String create_ticket_path = "https://api.weixin.qq.com/cgi-bin/qrcode/create";  
    // 通过ticket换取二维码  
    private String showqrcode_path = "https://mp.weixin.qq.com/cgi-bin/showqrcode";  
    
    @RequestMapping("getQrcode")
    public @ResponseBody String getQrcode(@RequestParam(value = "sceneId")int sceneId) throws Exception{
    
        
        String ticket = createTempTicket(tokenService.getToken(),"2592000",sceneId);
        LOGGER.info("get wechat qrcode  ==> start");
        LOGGER.info("sceneId :"+sceneId);
        LOGGER.info("ticket :"+ticket);
        LOGGER.info("get wechat qrcode  ==> end");
        return ticket;
    }
    /** 
     * 创建临时带参数二维码 
     * @param accessToken 
     * @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。 
     * @param sceneId 场景Id 
     * @return 
     */  
    public String createTempTicket(String accessToken, String expireSeconds, int sceneId) {  
      
        TreeMap<String,String> params = new TreeMap<String,String>();  
        params.put("access_token", accessToken);  
        Map<String,Integer> intMap = new HashMap<String,Integer>();
        intMap.put("scene_id",sceneId);  
        Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();  
        mapMap.put("scene", intMap);  
        
        Map<String,Object> paramsMap = new HashMap<String,Object>();  
        paramsMap.put("expire_seconds", expireSeconds);  
        paramsMap.put("action_name", QR_SCENE);  
        paramsMap.put("action_info", mapMap);  
        String data = new Gson().toJson(paramsMap);  
        String tse = HttpRequestUtil.HttpsDefaultExecute(HttpRequestUtil.POST_METHOD,create_ticket_path,params,data);  
        
        JSONObject jsonObject = JSONObject.fromObject(tse);
        LOGGER.info("ticket :"+jsonObject.getString("ticket"));


     return showqrcode_path+"?ticket="+jsonObject.getString("ticket");
 }
accessToken就是调用微信接口的凭证token

(2)网站端:网站写一个调用微信生成二维码的接口

@RequestMapping("getQrcode")
    public @ResponseBody Hashtable getQrcode(int sceneId){
        
        System.out.println(sceneId);
        
        Hashtable param = new Hashtable();
        param.put("sceneId", sceneId);

        String qrcodePath = HttpUtil.postRequest(Constant.getValue("get_qrcode"), param);

        System.out.println(" qrcodePath ==> "+qrcodePath);
        param.put("path", qrcodePath);
        return param;
    }

直接使用http调用接口就行,Constant.getValue("get_qrcode")这个就是微信提供二维码接口的url

(3)微信端:微信处理用户请求(这个地址是微信公众号填的那个地址,微信服务器会将所有用户请求转发到这个地址)

// 事件推送
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
                // 事件类型
                String eventType = requestMap.get("Event");
                // 关注
                if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                 
                    //获取用户信息
                    String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
                    requestUrl = requestUrl.replace("ACCESS_TOKEN", tokenService.getToken())
                            .replace("OPENID", fromUserName);
                    JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET",null);
                    String nickname = jsonObject.getString("nickname");
                    String address = jsonObject.getString("country")+"-"+jsonObject.getString("province")+"-"+jsonObject.getString("city");
                    String headimgurl = jsonObject.getString("headimgurl");

            //将用户信息存入redis,key为唯一值(场景值)
                    Hashtable params = new Hashtable();
                    params.put("phoneIme", fromUserName);
                    params.put("state", 1);
                    params.put("location", address);
                    params.put("realName", nickname);
                    params.put("nickname", nickname);
                    params.put("headimgurl", headimgurl);
                    if(StringUtils.isNotBlank(eventKey)){
                        redisCacheTool.setDataToRedis(eventKey.replace("qrscene_", ""), 3600, params);
                        System.out.println("qrcode redis key ==> "+eventKey.replace("qrscene_", ""));
                        params.put("equipmentType", eventKey);
                    }
            //入库
                    HttpUtil.postRequest(Constant.getValue("UPDATE_USER"), params);
                    
                }
                // 取消关注
                else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
                    // TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复
                    Hashtable params = new Hashtable();
                    params.put("phoneIme", fromUserName);
                    params.put("state", 0);
                    HttpUtil.postRequest(Constant.getValue("UPDATE_USER_ANS"), params);
                    
                }
                // 扫描带参数二维码
                else if (eventType.toLowerCase().equals(MessageUtil.EVENT_TYPE_SCAN)) {
                    // TODO 处理扫描带参数二维码事件
if(StringUtils.isNotBlank(eventKey)){
                        
                        String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
                        //获取用户信息
                        requestUrl = requestUrl.replace("ACCESS_TOKEN", tokenService.getToken())
                                .replace("OPENID", fromUserName);
                        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET",null);
                        String nickname = jsonObject.getString("nickname");
                        String address = jsonObject.getString("country")+"-"+jsonObject.getString("province")+"-"+jsonObject.getString("city");
                        String headimgurl = jsonObject.getString("headimgurl");
              //将用户信息存入redis,key为唯一值(场景值)
                        Hashtable params = new Hashtable();
                        params.put("nickname", nickname);
                        params.put("headimgurl", headimgurl);
                        params.put("location", address);
                        redisCacheTool.setDataToRedis(eventKey, 3600, params);
                        System.out.println("qrcode redis key ==> "+eventKey);
                    }
                    
                    
                    respContent = "返回的信息";
                    textMessage.setContent(respContent);
                    respXml = MessageUtil.messageToXml(textMessage);
                }

(4)网站端:登陆页面中做轮训,每隔几秒查询一次redis,如果有用户信息就登陆

var timestamp = new Date().getTime() + "";
    var str = timestamp.substring(8, timestamp.length);
    
        window.setInterval(function() {
        
        getUser(cont);
        
    }, 10000);

        function getUser() {
        $.ajax({
            type : 'get',
            data : {
                sceneId : str
            },
            dataType : 'json',
            url : "getUser.do",
            success : function(data) {

                if (data.msg == "success") {
                    location.reload(); 
                }

            },
            error : function(data) {

                if (data.msg == "success") {
                    location.reload();
                }

            }
        });
    }

 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值