前段时间公司网站登录注册改版,做了基于微信的第三方授权登录和注册,下面说的是网站应用微信授权实现登录注册,。踩了一些坑,现在写下来, 刚好梳理一下之前的思路, 如果能帮到有需要的人,那更好了。
微信授权登陆的优点是, 通过接入微信登录功能,用户可使用微信帐号快速登录你的网站,降低注册门槛。 这是微信官方文档微信OAuth2.0授权登录的流程图,后来又做了钉钉登录,QQ登录,发现都是一样的流程和原理, 都是基于OAuth2.0实现的,这个会了,钉钉登录,qq登录也就会了,一通百通。
进入正题, 准备工作简单说下, 在微信开放平台注册账号, 配置好AppID和AppSecret,设置好授权回调域名(注:重要,授权回调地址必须在此域名下)。
第一步:获取code
请确认你的网站应用已经获取了网页授权作用域(scope=snsapi_login), 你可以在前端放置或者在后端重定向到 以下链接:https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect ,
参数说明:
注意, redirect_uri需要进行urlEncode编码, 必须在授权域名下。不然会出现redirect_url错误的提示,授权失败。用户同意后会重定向到redirect_uri的路由上,并带上code和state参数。redirect_uri?code=CODE&state=STATE, 到这一步获取到了code。
例如,问卷网微信登录
也可以在自己的网站页面嵌入微信登录二维码,用户使用微信扫码授权后通过JS将code返回给网站,这样无需跳转到微信域名下 登录再返回,流畅性更好些。
例如:问卷网网页内嵌微信登录二维码
自己网页嵌入微信登录二维码需要在页面引入微信的JS文件(日了吉娃娃,复制不过来了,只能截图了):
在需要使用微信登录的地方实例以下JS对象
var obj = new WxLogin({
id:"login_container",
appid: "",
scope: "",
redirect_uri: "",
state: "",
style: "",
href: ""
});
第二步, 通过code获取access_token
通过上一步获取到的code参数,获取access_token
请求方法: GET
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&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"}
参数说明:
这一步获取到, access_token, openid, unionid, 这里对三个参数进行, access_token 是调用授权接口的调用凭证,这个access_token不需要进行缓存。还有一个access_token 是全局唯一接口调用凭据是需要缓存下来,有效期为两小时,有调用频次限制的。openid是这个用户对应当前应用的唯一标识,比如说,你只有一个网站应用,那个openid就是用户对应你的网站应用的唯一标识。 后来,你又新开发了个app,和公众号,那么你的每个应用对应同一个用户是有不同openid的, 这个时候你肯定需要同一个用户对应你的不同应用具有唯一性标示,这样才能把各个应用打通,这个时候就需要使用unionid了。你需要把你的公众号和应用绑定在同一开放平台下。同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。这就是unionid的主要作用。
第三步:使用access_token 获取用户信息
请求方法: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
参数说明:
正确返回结果:
{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
至此,已经获取到用户信息。可以建立用户会话。实现用户的注册和登陆。
使用openid获取unionid
做网站应用微信授权中间遇到点小插曲, 因为公司业务之前是用微信公众号实现的授权,保存的是openid, 做了网站应用之后就不能使用openid作为用户数据表的微信字段了,需要使用unionid才能保证公司多个应用对于同一用户的唯一性。所以, 需要把之前的几十万用户的openid更换为unionid在用户数据表里保存。后来,查了下文档,微信提供了openid转unionid的接口。
第一步, 先获取全局唯一接口调用凭据access_token。
接口调用说明:
https请求方式: GET,
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
参数说明:
注意, 这个access_token 跟上面微信授权提到的access_token没有半毛钱关系, 这个access_token 需要缓存下来,因为这个接口有调用频次限制, 好像每天最多可以调用5000次,可以保存在redis或者memcache里,设置过期时间为7200秒,最好小于7200 ,比如你可以设置7000后过期,过期后重新调用这个接口获取。
第二步,获取Unionid
接口调用说明
http请求方式: GET
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
参数说明:
正常情况下,微信会返回下述JSON数据包给公众号
{
"subscribe": 1,
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
"nickname": "Band",
"sex": 1,
"language": "zh_CN",
"city": "广州",
"province": "广东",
"country": "中国",
"headimgurl":"http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"subscribe_time": 1382694957,
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
"remark": "",
"groupid": 0,
"tagid_list":[128,2]
}
参数说明:
这样就用用户之前保存的openid 获取到Unionid了。
写了个多线程调用微信的接口,半个多小时就把几十万用户的openid、更换为了Unionid了。
有不对的地方,或者疑问欢迎留言。