微信扫一扫登录网站

微信网站扫一扫登录

个人blog+bbs www.youngboy.vip


上手须知

要想使用微信扫一扫就可以登录网站,首先要有微信开发平台账号,并且通过开发者资质认证(认证需要通过审核,审核费300人民币),然后添加网页应用准备网站信息登记表等信息提价审核,有公众号的可以绑定公众号,最终你会得到 appid 和 appsecret 然后就可以愉快的玩耍了

科普微信授权原理

微信用户->第三方应用: 请求登录第三方应用
第三方应用->微信开发平台: 请求oauth2授权
微信开发平台->微信用户: 请求用户确认
微信用户->微信开发平台: 用户确认
微信开发平台-> 第三方应用: 拉起第三方应用或重定向到第三方的服务器,并带上code
第三方应用 -> 微信开发平台: 通过code加上appid appsecret获取access_token
微信开发平台 -> 第三方应用: 返回用户相关信息

前端的打开方式

前端有两种打开方式

  1. 通过重定向到微信的页面然后用户扫描二维码授权,再重定向回第三方网站
  2. 通过js直接显示二维码登录,不用跳转微信页面

第一种方式是通过后台重定向过去的所以前端只需要写个链接就行了,第二种方式是在页面上直接显示二维码登录减少了跳页面的时间,这种方式需要在网页上用js实现,一般第二种用的比较多

使用js显示微信扫一扫二维码的打开方式

步骤1:在页面中先引入如下JS文件(支持https):

https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js

步骤2:在需要使用微信登录的地方实例以下JS对象:

var obj = new WxLogin({
     id:"login_container", // 需要显示的容器id
     appid: "",  // 公众号appid wx*******
     scope: "snsapi_login",  // 网页默认即可
     redirect_uri: "", // 授权成功后回调的url
     state: "", // 可设置为简单的随机数加session用来校验
     style: "black", // 提供"black"、"white"可选。二维码的样式
     href: "" // 外部css文件url,需要https
});

参数说明

参数 是否必须 说明
self_redirect true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。
id 第三方页面显示二维码的容器id
appid 应用唯一标识,在微信开放平台提交应用审核通过后获得
scope 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
redirect_uri 重定向地址,需要进行UrlEncode
state 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
style 提供"black"、"white"可选,默认为黑色文字描述
href 自定义样式链接,第三方可根据实际需求覆盖默认样式

用户点击确认授权后网页会自动跳转redirect_uri

前端扫码分析

https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js 的代码

!function(a, b, c) {
    function d(a) {
        var c = "default";
        a.self_redirect === !0 ? c = "true": a.self_redirect === !1 && (c = "false");
        var d = b.createElement("iframe"),
        e = "https://open.weixin.qq.com/connect/qrconnect?appid=" + a.appid + "&scope=" + a.scope + "&redirect_uri=" + a.redirect_uri + "&state=" + a.state + "&login_type=jssdk&self_redirect=" + c;
        e += a.style ? "&style=" + a.style: "",
        e += a.href ? "&href=" + a.href: "",
        d.src = e,
        d.frameBorder = "0",
        d.allowTransparency = "true",
        d.scrolling = "no",
        d.width = "300px",
        d.height = "400px";
        var f = b.getElementById(a.id);
        f.innerHTML = "",
        f.appendChild(d)
    }
    a.WxLogin = d
} (window, document);

上段代码主要功能是根据用户配置的消息在页面上嵌入一个iframe,我们看到的二维码是iframe和请扫描等提示语都是iframe中的

这里先给大家一个链接看看 点我
打开iframe的链接返回的是一个网页,再打开游览器的开发者工具可以看到一个长连接请求

https://long.open.weixin.qq.com/connect/l/qrconnect?uuid=081ciRVWnFkIOwL8&_=1534297144336

这个请求带有两个参数一个是 uuid 还有一个 是 _ 看样子应该是时间戳,这个请求在没扫描之前一直是阻塞的,如果27秒没有扫码会自动断开连接,并且返回一段js代码

window.wx_errcode=408;window.wx_code='';

再来看看网页中嵌入的一段代码,这里我省略了一些代码只留下比较重要的

!function() {
    function a(d) {
        jQuery.ajax({
            type: "GET",
            url: "https://long.open.weixin.qq.com/connect/l/qrconnect?uuid=011ZJt4N2TyhElXu" + (d ? "&last=" + d: ""),
            dataType: "script", //这里是script类型
            cache: !1,
            timeout: 6e4,
            success: function(d, e, f) {
                var g = window.wx_errcode;//这里为什么是window.wx_errcode呢 因为返回的格式是script 内容是 window.wx_errcode=408;window.wx_code='';
                switch (g) {
                case 405://如果是405证明用户已经同意授权登录 用js重定向并带上code
                    var h = "http://www.jianshu.com/users/auth/wechat/callback";
                    h = h.replace(/&/g, "&"),
                    h += (h.indexOf("?") > -1 ? "&": "?") + "code=" + wx_code + "&state=123";
                    var i = b("self_redirect");
                    if (c) if ("true" !== i && "false" !== i) try {
                        document.domain = "qq.com";
                        var j = window.top.location.host.toLowerCase();
                        j && (window.location = h)
                    } catch(k) {
                        window.top.location = h
                    } else if ("true" === i) try {
                        window.location = h
                    } catch(k) {
                        window.top.location = h
                    } else window.top.location = h;
                    else window.location = h;
                    break;
                case 404:
                    jQuery(".js_status").hide(),
                    jQuery("#wx_after_scan").show(),
                    setTimeout(a, 100, g);
                    break;
                case 403:
                    jQuery(".js_status").hide(),
                    jQuery("#wx_after_cancel").show(),
                    setTimeout(a, 2e3, g);
                    break;
                case 402:
                case 500:
                    window.location.reload();
                    break;
                case 408:
                    setTimeout(a, 2e3)
                }
            },
            error: function(b, c, d) {
                var e = window.wx_errcode;
                408 == e ? setTimeout(a, 5e3) : setTimeout(a, 5e3, e)
            }
        })
    }
    ...
} ();

上面的代码是一段自执行函数,链接一打开就会执行,在用户扫码之前请求是阻塞的success回调都不会执行,如果用户一直没有扫描二维码,请求在27秒内就会断开链接这时就会去执行success回调函数并且重新发起一个长连接重复以上步骤直到返回405

网页中的二维码解析后的结果是

https://open.weixin.qq.com/connect/confirm?uuid=0618LnlRCFd-jYeo

这个链接只有一个参数并且uuid和长连接请求的uuid是相同的,用游览器打开会提示Scope 参数错误或没有 Scope 权限,只能用微信打开才有用,微信的包不好抓希望有大神能够指点指点

后端的打开方式

重定向到微信页面的打开方式

登录你的网站应用
https://xxx.xxx.com/wechat/login.do
打开后需要重定向至微信的地址并带上必要的参数

https://open.weixin.qq.com/connect/qrconnect?
appid=wxbdc5610cc59c1631
&
redirect_uri=https%3A%2F%2Fxxx.xxx.com%2Fwechat%2Fcallback.do
&
response_type=code
&
scope=snsapi_login
&
state=3d6be0a4035d839573b04816624a415e#wechat_redirect

这里需要变的参数是appid和redirect_url

访问以上链接微信开发平台会重定向到redirect_uri的网址上,并且带上codestate参数,如果用户没有授权就不会有code参数,仅会带上state参数

https://xxx.xxx.com?code=xxx&state=xxx

后台根据code获取用户信息封装

获取用户信息的步骤

  • 通过code获取access_token
  • 通过access_token调用接口

这里使用了weixin-java-tools工具来获取用户信息
github地址 传送门

public WxMpUser getWxUser(String code) {
        if (code == null) {
            return null;
        }
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken = null;
        WxMpUser wxMpUser = null;
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
            wxMpOAuth2AccessToken = wxMpService.oauth2refreshAccessToken(wxMpOAuth2AccessToken.getRefreshToken());
            wxMpUser = wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, null);
        } catch (WxErrorException e) {
            return null;
        }

        return wxMpUser;
    }

社区讨论

Java 长连接模拟微信登录

[图片上传失败...(image-6193f9-1557819001579)]

实现原理

使用Servlet3异步接口实现非阻塞长连接接口, 异步上下文对象使用 ScheduledExecutorService 线程池定时调度 事件总线使用了 guava 中的 EventBus 实现

有兴趣可以去瞧瞧,目前oauth2+openId扫码登录正在开发中... 欢迎fork添加代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容