欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

手把手教程用Java实现微信公众号扫码登录功能-二、使用步骤

最编程 2024-02-22 07:53:56
...

1. 使用微信工具包

build.gradle里面加入如下代码后重新获取依赖

dependencies {
	...
	compile 'com.github.binarywang:weixin-java-mp:3.3.0'
	...
}

2. 创建数据表

数据表是两边沟通的桥梁,qrcode_ticket 主要是参数二维码的主要信息,session_code是用户的登录会话标识。open_id为公众号产生的open_id。

CREATE TABLE `user_login_session` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `qrcode_ticket` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `session_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `open_id` varbinary(255) DEFAULT NULL,
  `create_time` timestamp NULL DEFAULT NULL,
  `update_time` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `qrcode_ticket` (`qrcode_ticket`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

3. 登录页面代码逻辑

后端逻辑,当用户没有session_code的时候跳转到登录页面,这个时候登录页面需要展示一个带参数的二维码。后端核心代码逻辑如下。

@GetMapping("/login")
public ModelAndView login()
{
    HashMap<String, String> map = new HashMap<String, String>();
    String marketQrcode;
    //这里是生成一个任意随机字符串
    String qrcodeTicket =  RandomUtil.generateDeviceToken(); 
    try{
        String scene = "login_" + qrcodeTicket;
        WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(scene,600);
        marketQrcode = UserService.SHOW_QRCODE_WX_BASE_URL + ticket.getTicket();
    }catch (Exception e) {
        marketQrcode = "";
    }
    map.put("qrcodeUrl", marketQrcode);
    map.put("qrcodeTicket", qrcodeTicket);
    //存到上面的表里面
    userLoginSessionService.create(qrcodeTicket);
    return new ModelAndView("login", map);
}

前端登录页面显示出来二维码。通过上面代码可以看到qrcodeUrl就是要展示的二维码的地址,qrcodeTicket就是联系二维码和登录状态的中间参数。

<div>
 <img style="width:160px;" src="${qrcodeUrl}" />
</div>

这个参数给到前端,前端会一直带着这个qrcodeTicket每隔3s轮训发起请求,用户扫码登录成功之后,会对这个qrcodeTicket生成一个session_code,当发现这个session_code不为空时候表示用户登录成功了。就可以带着跳转到目标页面了。通过这个session_code去授权。

<script>
loopTimes = 0;
var timer1 = setInterval(function(){
    checkLogin()
},3000)
function checkLogin() {
    loopTimes ++
    if(loopTimes > 30){
        clearInterval(timer1)
    }
    $.ajax({
        type: 'get',
        url: '/target/checkLogin',
        dataType: 'json',
        data: {
            qrcodeTicket: '${qrcodeTicket}'
        },
        success:function(res){
            // 如果生成了sessionCode表示登录成功
            if(res.sessionCode) {
                window.location.href = "/target/go?sessionCode=" + res.sessionCode
            }
        }
    })
}
</script>

java后端代码检查登录情况。

@GetMapping("/checkLogin")
@ResponseBody
public UserLoginSession checkLogin(@RequestParam String qrcodeTicket)
{
    HashMap<String, String> map = new HashMap<String, String>();
    return userLoginSessionService.findByQrcodeTicket(qrcodeTicket);
}

4. 验证微信公众号登录

微信公众号登录成功后,会触发handle方法,这个时候需要在这个方法里面处理相关逻辑,生成sessionCode。核心代码如下。

@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
                                WxSessionManager sessionManager) {
    String eventKey = wxMessage.getEventKey();
    String scanQrcodeInfo = eventKey.startsWith("qrscene_") ? eventKey.replace("qrscene_", "") : eventKey;
    String qrcodeTicket = scanQrcodeInfo.replaceAll("login_", "");
    String sessionCode = RandomUtil.generateDeviceUuid();
    userLoginSessionService.updateSessionCode(qrcodeTicket, sessionCode, wxMessage.getFromUser());
    return msg("登录成功", wxMessage);
}

通过以上的操作,基本上就实现了微信公众号扫码登录的功能。