java实现扫码关注公众号--pc登录网站

登录流程如下

1.服务端获取accessToken
2.服务端请求微信接口生成带参数的二维码,微信会返回{二维码ticket,二维码有效时间,二维码图片地址}等信息。服务端将ticket响应给前端,前端拿ticket开始轮询请求服务器
3.用户扫码关注后,微信服务器会通知微信接口配置的url接口并携带{FromUserName:发送方的openid,Event:事件类型 subscribe(订阅)、unsubscribe(取消订阅),二维码的ticket}等信息
4.服务器拿到openId和ticket 将 ticket作为key,openId作为value 存储至redis。表明此用户已扫码关注。
5.当前端拿ticket 轮询请求服务器时,服务端拿ticket去redis中查询。如果存在即扫码或关注成功,查看openid是否已注册,如已注册登录成功,如未注册则去注册。业务处理完成后服务端删除redis中的数据。

微信配置:
基本配置–》服务器配置。服务器地址(URL)即事件触发时被通知的接口

1. 服务端获取accessToken

1.accessToken 不建议使用时去获取
2. accessToken 失效性是两个小时,所以我们在redis存储1小时时间

    @Override
    public String getPubAccessToken() {
        String pubAccessToken;
        Object obj = redisTemplate.opsForValue().get("pubAccessToken");
        if (obj != null) {
            pubAccessToken = (String)obj;
            return pubAccessToken;
        } else {
            log.info("开始获取pubAccessToken");
            try {
                String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxPubPayProperties.getAppId() + "&secret=" + wxPubPayProperties.getAppSecret();
                ResponseEntity<Map> entity =  restTemplate.exchange(url,HttpMethod.GET, null,Map.class);
                Map<String,Object> map = entity.getBody();
                pubAccessToken = map.get("access_token") != null ? String.valueOf(map.get("access_token")) : null;
                if (StringUtils.isNotEmpty(pubAccessToken)) {
                    redisTemplate.opsForValue().set("pubAccessToken", pubAccessToken, 3600, TimeUnit.SECONDS);
                    return pubAccessToken;
                } else {
                    return null;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    }
  1. 服务端生成带参数的二维码
    @Override
    public AppResult createQrCode(String sceneStr) {
        String pubAccessToken = getPubAccessToken();
        String url ="https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + pubAccessToken;

        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Content-type", "application/json; charset=utf-8");
        HttpEntity<String> requestEntity = new HttpEntity<>("{\"expire_seconds\": 3600, \"action_name\": \"QR_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": " + sceneStr +" }}}", requestHeaders);
        Map<String,Object> map  =  restTemplate.postForObject(url,requestEntity,Map.class);
        // map为响应参数 其中有ticket expire_seconds url 
        return AppResult.successReturnDate(map);
    }

  1. 被微信服务器通知的服务端接口

    1.将token、timestamp、nonce三个参数进行字典序排序
    2.将三个参数字符串拼接成一个字符串进行sha1加密
    3.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
    4.接收事件推送 查看xmlData里的参数

    @PostMapping("weChatNotice")
    public String weChatNotice(@RequestBody String xmlData,String signature,Long timestamp,String nonce, String echostr) {
        wxService.weChatNotice(xmlData);
        return echostr;
    }

  1. 绑定ticket和openid至redis
    @Override
    public void weChatNotice(String xmlData) {
        // xml转map
        Map<String, String> resultMap = WxPayKit.xmlToMap(xmlData);
        String ticket = resultMap.get("Ticket");
        if (StringUtils.isNotEmpty(ticket)) {
            String openId = resultMap.get("FromUserName");
            // 将ticket 和 openId 存储进redis
            redisTemplate.opsForValue().set(ticket, openId, 3600, TimeUnit.SECONDS);
        }
    }

  1. 被前端轮询的接口
    @Override
    public AppResult wxLogin(String ticket) {
        // 判断 用户是否已扫码关注
        Map<String,Object> map = new HashMap<>();
        Object obj = redisTemplate.opsForValue().get(ticket);
        if (obj == null) {
            return AppResult.errorReturn(10024, "用户还未扫码关注");
        } else {
            String openId = (String) obj; 
            // 用户已扫码登录,删除redis
            redisTemplate.delete(ticket);
            // 查询openId是否已绑定手机号注册
            map.put("openId",openId);
            Member member = memberMapper.getMemberOpenId(openId);
            if (member == null) {
                map.put("state",1);
                return  AppResult.successReturnDate(map, "用户已扫码,但未注册");
            } else {
                map.put("state",0);
                return  AppResult.successReturnDate(map, "用户已扫码,已注册");
            }
        }
    }

  1. 根据openId获取微信用户信息
        public Map<String,Object> getWxUserInfo(String openId) {
        String pubAccessToken = getPubAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + pubAccessToken + "&openid=" + openId + "&lang=zh_CN";
        ResponseEntity<Map> entity =  restTemplate.exchange(url,HttpMethod.GET, null,Map.class);
        Map<String,Object> map = entity.getBody();
        return map;
    }


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java公众号扫码登录三方网站的具体过程如下: 1. 需要实现一个Java公众号登录功能,使用户可以通过扫描二维码进行登录。首先,在Java公众号中生成一个登录二维码,可以使用一些第三方库(如Google的ZXing库)生成二维码图像。 2. 用户在三方网站登录页面中选择使用Java公众号扫码登录网站生成一个唯一的登录状态码(token)并将其存储在服务器上。 3. Java公众号用户打开扫码登录功能,并使用手机相机或者Java公众号内置的扫码功能扫描登录页面上的二维码图像。 4. Java公众号接收到用户的扫码请求后,将请求的参数(如token)发送给服务器进行验证。服务器通过验证参数的有效性,确认用户的登录请求,并返回一个登录授权码(authorization code)给Java公众号。 5. Java公众号接收到服务器返回的授权码后,再次向服务器发起请求,使用授权码来获取用户的登录凭证(access token)。服务器验证授权码的有效性,并返回一个包含访问令牌的响应给Java公众号。 6. Java公众号接收到服务器返回的访问令牌后,将其存储在本地,即可代表用户在三方网站登录成功。Java公众号可以使用访问令牌来进行后续的操作,如获取用户信息、访问用户的资源等。 通过以上步骤,Java公众号可以实现扫码登录三方网站的功能。整个过程中,涉及到Java公众号与服务器的交互,以及服务器对用户身份的验证和授权操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亿万富翁进化中

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值