使用微信帐号登录网站的实现

TOC

前言

https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
其实官方已经有文档,这里记录一下实现的过程,以及其中一些细节。

准备工作

1、去微信开放平台申请账号
https://open.weixin.qq.com/
2、账号申请完成之后,进行开发者资质认证,认证一次就好,不需要像公众号那样年审。

3、创建网站应用,如果是APP的则创建移动应用


审核通过之后,就默认获得了微信登陆的接口能力,接下来就是实现微信登陆的过程了。

实现

请求code

微信登陆支持两种方式获取code,第一种是跳转新的页面,第二种是内嵌iframe,就体验来说,优先选择第二种,这里也主要介绍第二种。
先上代码,用的是vuejs

<Button @click="wxLogin" type="success" long>微信登录</Button>
<div v-show="isShowWxLogin" id="wx_login_modal">

wxLogin() {
    console.log("微信登录");
    new WxLogin({
        id: "wx_login_modal",
        appid: "wx692f8f2a*********",
        scope: "snsapi_login",
        redirect_uri: encodeURI("https://*******/"),
        state: "null",
        style: "white",
        href: "https://********/css/wechat_login.css"
    });
    this.isShowWxLogin = true;
}

记得要先在页面中先引入如下JS文件(支持https):
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
然后在需要使用微信登录的地方实例以下WxLogin对象:

参数是否必须
说明
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"可选,默认为黑色文字描述。详见文档底部FAQ
href
自定义样式链接,第三方可根据实际需求覆盖默认样式。详见文档底部FAQ

其中,可以在调用wxLogin方法之前,预请求服务器生成一个伪随机数,返回附到state里进行校验,或者附带一些附加的参数。
href用于自定义样式,可以先不填,用chrome调试样式并记录好css,保存成文件上传服务器再填css地址。
redirect_uri需要预先UrlEncode,若登录成功,会附带code和state重定向到该地址。

通过code获取access_token

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

参数是否必须说明
appid
应用唯一标识,在微信开放平台提交应用审核通过后获得
secret
应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code
填写第一步获取的code参数
grant_type
填authorization_code

正确的返回:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"

}

需要注意的是同一个微信开放平台账户下的移动应用、网站应用和公众账号(包括小程序),用户的UnionID是唯一的。
我们应该优先采用unionid作为关联微信账户体系的id。
由于系统要做到前后端分离,通过无状态接口调用,所以会重定向到前端的地址,由前端负责识别出code和state后进行调用后端提供的接口,返回jwt以及相关信息。
下面是后端php代码:

    function wechatLogin()
    {
        $code = request()->get('code');
        $appid = "wx692f8f2******";
        $secret = "c272e97be6573729********";
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";
        $res = file_get_contents($url);
        $res = json_decode($res, true);
       ……处理逻辑,返回jwt
    }

通过access_token调用接口

一般获取到unionid之后进行绑定就结束了,下次用户再扫码匹配unionid即可,也可以用access_token获取用户信息进行保存,见
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Authorized_Interface_Calling_UnionID.html

授权作用域(scope)接口接口说明
snsapi_base
/sns/oauth2/access_token
通过code换取access_token、refresh_token和已授权scope
snsapi_base
/sns/oauth2/refresh_token
刷新或续期access_token使用
snsapi_base
/sns/auth
检查access_token有效性
snsapi_userinfo
/sns/userinfo
获取用户个人信息

首次登录

如果平台不采用微信账号体系,也就是原本存在账号密码登陆,手机号登陆等,
那么用户第一次使用微信登陆时,需要进行一次账号绑定。
1、判断unionid是否绑定
2、若未绑定,则临时保存unionid,弹出注册/登录页面
3、提交时候,附带上unionid,直接绑定。

也也可以在用户中心里提供微信绑定按钮,下次登录的时候就没那么麻烦了。

总结

微信登陆方便了用户一键扫码登陆,除了官方的方案,还有另外2种,这里仅提供思路。

(1)实现关注公众号登录,需要认证的服务号,因为要生成带参二维码。
1、用户点击微信登陆,生成一个随机数参数,用于生成带参数的二维码,供前端显示
https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html
2、用户扫码,关注公众号,在关注事件消息里获取用户信息,识别出随机数参数作为缓存key,用户信息作为value,保存缓存。
3、前端每隔3秒附带随机数参数轮询接口,查询是否有该随机数参数缓存,若存在则判断是否绑定。
4、若绑定则返回用户信息,没有则提示注册或登录。

(2)实现扫码登陆,需要认证的公众号。
与上面不同的是,这里二维码自己生成即可,然后通过网页授权的方式获取用户信息,其余逻辑大同小异。

原文地址:https://www.cnblogs.com/leestar54/p/14127508.html