概述
转自:http://www.cnblogs.com/linjunjie/p/6378166.html#3902595
说下需求,一个网页要在三类容器运行,公司app,微信自动登录,浏览器。
假设是已经申请完成各平台开发者账号。
先来简单的,微博和QQ
微博:
引入微博JS
<script src="http://tjs.sjs.sinajs.cn/open/api/js/wb.js?appkey=*******&debug=true" type="text/javascript" charset="utf-8"></script>
appkey中,填入你的微博开发者id(替换****)
1
|
<
span
id="wb_connect_btn">微博登录按钮</
span
>
|
在你的页面微博登录按钮标签上,加入以上id。页面加载时,微博会自动加载样式,你也可以自己强行修改。
<script> WB2.anyWhere(function (W) { W.widget.connectButton({ id: "wb_connect_btn", type: '3,2', callback: { login: function (o) { //登录后的回调函数
console.log(o); thirdparty(null,null,o.avatar_hd, o.name ,3, o.id);//个人方法 try{ document.getElementsByClassName('loginout')[0].click(); //页面需求,当前页面登录完成之后,不进行跳转,所以模拟点击事件,让微博账号在当前域中退出。不影响下次登录。(元素为微博动态添加)
//微博没有提供退出方法。下面的logout为另一种开发模式调用。
}catch(e){ console.log(e); } }, logout: function () { //退出后的回调函数 } } }); }); </script>
将以上标签全部加入html中。
至此,只要在页面中登录之后,就能在控制台看到返回数据。当然,测试要在微博注册的域下。
QQ登录:
和微博一样,引入JavaScript文件
<script type="text/javascript" src="http://qzonestyle.gtimg.cn/qzone/openapi/qc_loader.js" data-appid="******" charset="utf-8"></script>
微博类似,替换为你的appid
<span id="qqLoginBtn"></span>
登录标签中加入id标识
然后JavaScript中加入以下代码:
QC.Login({ //btnId:插入按钮的节点id,必选 btnId:"qqLoginBtn", //用户需要确认的scope授权项,可选,默认all scope:"all", //按钮尺寸,可用值[A_XL| A_L| A_M| A_S| B_M| B_S| C_S],可选,默认B_S size: "B_S" }, function(reqData, opts){//登录成功 //根据返回数据,更换按钮显示状态方法 console.log(reqData);//查看返回数据 QC.Login.getMe(function(openId, accessToken){//获取用户的openId console.log('QQOPENID:'+openId); thirdparty(null,null,reqData.figureurl_qq_2,reqData.nickname,1,openId); QC.Login.signOut();//退出QQ登录调用事件 }); } );
测试要在QQ中注册的域名下。重要的事情,再说一遍。
QQ和微博登录,大致相同,只要引入JS文件,然后直接调用方法即可,QQ比微博更和谐,直接提供退出事件。上面代码中有。。
现在来说最蛋疼的微信登录。
微信登录提供两种方法:
第一种,扫码登录:
需要在微信开发者平台中,注册获取appId。
微信登录按钮:
<span class="weixin-login"></span>
在你微信登录按钮上,添加点击事件,执行以下代码:
$('.weixin-login').on('click',function(){ window.location.href='https://open.weixin.qq.com/connect/qrconnect?' + 'appid=*******&redirect_uri=http%3a%2f%2fwww.xxxxxx.com%2f'+window.location.pathname.substr(1)+'&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect'; });
需要替换:
redirect_url:要想传当前url,直接encodeURIComponent(window.location.href) //当然,需要你自己进行拼接,不懂的留言
至此,当用户点击之后,跳转至扫码界面:
例如:https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e
至此,拿到第一步令牌,code。在你的回调页面中,你要获取url中的code去和微信换取下一步的令牌。因为换取下一步的令牌需要涉及到跨域请求,但是微信不让跨域请求,只能在后台进行后续事项。
第二步,后台请求:https://api.weixin.qq.com/sns/oauth2/access_token?appid=[APPID]&secret=[SECRET]&code=[CODE]&grant_type=authorization_code
替换中括号中的数据。(我走的get请求)。
返回以下数据:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }
最后一步就不说了:
https://api.weixin.qq.com/sns/userinfo?access_token=[ACCESS_TOKEN]&openid=[OPENID]
替换成上次请求获取到的数据,再请求一次,获奖用户基本信息。
1、OAuth2.0
OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。
在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。
微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:
1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数; 2. 通过code参数加上AppID和AppSecret等,通过API换取access_token; 3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
获取access_token时序图:
1、这里填写的是域名(是一个字符串),而不是URL,因此请勿加http://等协议头; 2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权
5.1、请求url说明
第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识(前面认证网页应用中获得) |
redirect_uri | 是 | 重定向地址,需要进行UrlEncode(前面认证网页应用中获得) |
response_type | 是 | 填code |
scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 |
state | 否 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
redirect_uri?code=CODE&state=STATE
若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
redirect_uri?state=STATE
5.2、事例:
一号店的微信二维码链接如下:
https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect
将其复制到浏览器中打开即可获得一号店的二维码,二维码页面如下:
通过使用微信客户端的扫一扫功能,扫描该二维码,即会跳转到上面填写redirect_uri所在的地址上。假如用户同意授权,这里就获得了微信返回的code参数了。
6、获取用户信息
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" }
参数 | 说明 |
---|---|
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
unionid | 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。 |
错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}
- code参数的超时时间是5分钟,且每次请求的code参数的值都不一样。
- access_token的超时时间是32分钟。
- access_token有效且为超时;
- 微信用户已授权给第三方应用账号相应接口作用域(scope)【在二维码生成连接那里填写】
授权作用域(scope) | 接口 | 接口说明 |
---|---|---|
snsapi_base | /sns/oauth2/access_token | 通过code换取access_token、refresh_token和已授权scope |
/sns/oauth2/refresh_token | 刷新或续期access_token使用 | |
/sns/auth | 检查access_token有效性 | |
snsapi_userinfo | /sns/userinfo | 获取用户个人信息 |
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 调用凭证(上一个请求中获得) |
openid | 是 | 普通用户的标识,对当前开发者帐号唯一(上一个请求中获得) |
lang | 否 | 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN |
返回说明
正确的Json返回结果:
{ "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 | 普通用户的标识,对当前开发者帐号唯一 |
nickname | 普通用户昵称 |
sex | 普通用户性别,1为男性,2为女性 |
province | 普通用户个人资料填写的省份 |
city | 普通用户个人资料填写的城市 |
country | 国家,如中国为CN |
headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 |
privilege | 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) |
unionid | 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 |
错误的Json返回示例:
{ "errcode":40003,"errmsg":"invalid openid" }
7、总结
最近着手开发了微信网页扫码登录和公众号授权登录收获颇丰,两者的开发很类似。以下是我个人摸索过程中发现的两者的异同:
- 两者都可以通过微信客户端扫码授权的方式,让第三方页面获得微信用户的一些基本信息(昵称、性别、所在地、在微信唯一标示等……)。他们都是通过提供一个链接让用户授权的方式。但网页版需要在页面打开二维码之后授权,而公众号则需要用户先关注了我们的公众号,然后点开公众号里面的链接,确认授权即可。
- 网页扫码登录需要将授权的链接(二维码链接)在网页中打开、而公众号授权登录的链接必须要微信客户端中打开。
- 无论网页扫码登录还是在公众号中授权登录,都是通过授权的方式获得一个code参数,之后通过code参数获取access_token和openid和通过access_token和openid去获取用户的基本信息的请求链接是一样的。
- 在开发公众号授权登录的过程中,我发现了有测试账号的提供,足以满足我们的测试和开发,但在开发网页扫码时,暂时未发现哪里能获取测试账号,我是通过申请获取的。(希望知道哪里有测试账号的请求高手赐教)。
https://api.weixin.qq.com/sns/oauth2/access_token?appid=AppID&secret=AppSecret&code=00294221aeb06261d5966&grant_type=authorization_code
这是接口在线调试工具:
这是错误码说明文档:
http://mp.weixin.qq.com/wiki/14/bb5031008f1494a59c6f71fa0f319c66.html
微信网页第三方登录原理
微信开放平台和公众平台的区别
1.公众平台面向的时普通的用户,比如自媒体和媒体,企业官方微信公众账号运营人员使用,当然你所在的团队或者公司有实力去开发一些内容,也可以调用公众平台里面的接口,比如自定义菜单,自动回复,查询功能。目前大多数微信通过认证之后,都在做这个事情。
mp.weixin.qq.com
2.开放平台面向的开发者和第三方独立软件开发商。我觉得开发平台最大的开放就是微信登录。当年腾讯没有花大力气去做统一登录这个事情,导致目前各个网站都要弄一套登录机制。好在他们现在认清了局势。开发者或软件开发商,通过微信开放提供的平台和接口,可以开发适合企业的电子商务网站,扫描二维码进去一个游戏界面,然后去购买商品等。当然后续开放平台要开放支付接口,那么类似口袋通这种软件开发厂商,就可以为大型,中小企业提供微信小店这种服务和软件了。
open.weixin.qq.com
公众平台就是服务号订阅号的管理开发后台。
开发平台说得通俗一点就是实现手机里边安装软件的内容一键分享朋友圈;
下面的第三方登陆就是依托于开放平台(open.weixin.qq.com)的功能
准备工作
网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。
在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。
授权流程说明
微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。
微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为:
1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。
获取access_token时序图:
第一步:请求CODE
第三方使用网站应用授权登录前请注意已获取相应网页授权作用域(scope=snsapi_login),则可以通过在PC端打开以下链接:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“该链接无法访问”,请检查参数是否填写错误,如redirect_uri的域名与审核时填写的授权域名不一致或scope不为snsapi_login。
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识 |
redirect_uri | 是 | 重定向地址,需要进行UrlEncode |
response_type | 是 | 填code |
scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 |
state | 否 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
返回说明
用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
redirect_uri?code=CODE&state=STATE
若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
redirect_uri?state=STATE
请求示例
登录一号店网站应用
https://passport.yhd.com/wechat/login.do
打开后,一号店会生成state参数,跳转到
https://open.weixin.qq.com/connect/qrconnect?appid=wxbdc5610cc59c1631&redirect_uri=https%3A%2F%2Fpassport.yhd.com%2Fwechat%2Fcallback.do&response_type=code&scope=snsapi_login&state=3d6be0a4035d839573b04816624a415e#wechat_redirect
微信用户使用微信扫描二维码并且确认登录后,PC端会跳转到
https://passport.yhd.com/wechat/callback.do?code=CODE&state=3d6be0a4035d839573b04816624a415e
为了满足网站更定制化的需求,我们还提供了第二种获取code的方式,支持网站将微信登录二维码内嵌到自己页面中,用户使用微信扫码授权后通过JS将code返回给网站。
JS微信登录主要用途:网站希望用户在网站内就能完成登录,无需跳转到微信域下登录后再返回,提升微信登录的流畅性与成功率。 网站内嵌二维码微信登录JS实现办法:
步骤1:在页面中先引入如下JS文件(支持https):
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
步骤2:在需要使用微信登录的地方实例以下JS对象:
var obj = new WxLogin({
id:"login_container",
appid: "",
scope: "",
redirect_uri: "",
state: "",
style: "",
href: ""
});
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
id | 是 | 第三方页面显示二维码的容器id |
appid | 是 | 应用唯一标识,在微信开放平台提交应用审核通过后获得 |
scope | 是 | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 |
redirect_uri | 是 | 重定向地址,需要进行UrlEncode |
state | 否 | 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 |
style | 否 | 提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ |
href | 否 | 自定义样式链接,第三方可根据实际需求覆盖默认样式。详见文档底部FAQ |
第二步:通过code获取access_token
通过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"
}
参数 | 说明 |
---|---|
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
unionid | 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 |
错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}
刷新access_token有效期
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
请求方法
获取第一步的code后,请求以下链接进行refresh_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识 |
grant_type | 是 | 填refresh_token |
refresh_token | 是 | 填写通过access_token获取到的refresh_token参数 |
返回说明
正确的返回:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数 | 说明 |
---|---|
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
错误返回样例:
{"errcode":40030,"errmsg":"invalid refresh_token"}
注意:
1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上。
建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。
第三步:通过access_token调用接口
获取access_token后,进行接口调用,有以下前提:
1. access_token有效且未超时;
2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。
对于接口作用域(scope),能调用的接口有以下:
授权作用域(scope) | 接口 | 接口说明 |
---|---|---|
snsapi_base | /sns/oauth2/access_token | 通过code换取access_token、refresh_token和已授权scope |
/sns/oauth2/refresh_token | 刷新或续期access_token使用 | |
/sns/auth | 检查access_token有效性 | |
snsapi_userinfo | /sns/userinfo | 获取用户个人信息 |
其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。
接口调用方法可查阅《微信授权关系接口调用指南》
F.A.Q
1. 什么是授权临时票据(code)?
答:第三方通过code进行获取access_token的时候需要用到,code的超时时间为10分钟,一个code只能成功换取一次access_token即失效。code的临时性和一次保障了微信授权登录的安全性。第三方可通过使用https和state参数,进一步加强自身授权登录的安全性。
2. 什么是授权作用域(scope)?
答:授权作用域(scope)代表用户授权给第三方的接口权限,第三方应用需要向微信开放平台申请使用相应scope的权限后,使用文档所述方式让用户进行授权,经过用户授权,获取到相应access_token后方可对接口进行调用。
3. 网站内嵌二维码微信登录JS代码中style字段作用?
答:第三方页面颜色风格可能为浅色调或者深色调,若第三方页面为浅色背景,style字段应提供"black"值(或者不提供,black为默认值),则对应的微信登录文字样式为黑色。相关效果如下:
若提供"white"值,则对应的文字描述将显示为白色,适合深色背景。相关效果如下:
4.网站内嵌二维码微信登录JS代码中href字段作用?
答:如果第三方觉得微信团队提供的默认样式与自己的页面样式不匹配,可以自己提供样式文件来覆盖默认样式。举个例子,如第三方觉得默认二维码过大,可以提供相关css样式文件,并把链接地址填入href字段
.impowerBox .qrcode {width: 200px;}
.impowerBox .title {display: none;}
.impowerBox .info {width: 200px;}
.status_icon {display:none}
.impowerBox .status {text-align: center;}
相关效果如下:
通过code获取access_token
接口说明
通过code获取access_token的接口。
请求说明
http请求方式: GET
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"
}
参数 | 说明 |
---|---|
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
错误返回样例:
{
"errcode":40029,"errmsg":"invalid code"
}
刷新或续期access_token使用
接口说明
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2.若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
请求方法
使用/sns/oauth2/access_token接口获取到的refresh_token进行以下接口调用:
http请求方式: GET
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 应用唯一标识 |
grant_type | 是 | 填refresh_token |
refresh_token | 是 | 填写通过access_token获取到的refresh_token参数 |
返回说明
正确的返回:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数 | 说明 |
---|---|
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
错误返回样例:
{
"errcode":40030,"errmsg":"invalid refresh_token"
}
接口说明
检验授权凭证(access_token)是否有效
请求说明
http请求方式: GET
https://api.weixin.qq.com/sns/auth?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 调用接口凭证 |
openid | 是 | 普通用户标识,对该公众帐号唯一 |
返回说明
正确的Json返回结果:
{
"errcode":0,"errmsg":"ok"
}
错误的Json返回示例:
{
"errcode":40003,"errmsg":"invalid openid"
}
获取用户个人信息(UnionID机制)
接口说明
此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,
可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。
请求说明
http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
参数说明
参数 | 是否必须 | 说明 |
---|---|---|
access_token | 是 | 调用凭证 |
openid | 是 | 普通用户的标识,对当前开发者帐号唯一 |
返回说明
正确的Json返回结果:
{
"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 | 普通用户的标识,对当前开发者帐号唯一 |
nickname | 普通用户昵称 |
sex | 普通用户性别,1为男性,2为女性 |
province | 普通用户个人资料填写的省份 |
city | 普通用户个人资料填写的城市 |
country | 国家,如中国为CN |
headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 |
privilege | 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) |
unionid | 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 |
错误的Json返回示例:
{
"errcode":40003,"errmsg":"invalid openid"
}
调用频率限制
接口名 | 频率限制 |
---|---|
通过code换取access_token | 1万/分钟 |
刷新access_token | 5万/分钟 |
获取用户基本信息 | 5万/分钟 |
第一步:填写服务器配置
第二步:验证服务器地址的有效性
第三步:依据接口文档实现业务逻辑
用户向公众号发送消息时,公众号方收到的消息发送者是一个OpenID,是使用用户微信号加密后的结果,每个用户对每个公众号有一个唯一的OpenID。此外,由于开发者经常有需在多个平台(移动应用、网站、公众帐号)之间共通用户帐号,统一帐号体系的需求,微信开放平台(open.weixin.qq.com)提供了UnionID机制。开发者可通过OpenID来获取用户基本信息,而如果开发者拥有多个应用(移动应用、网站应用和公众帐号,公众帐号只有在被绑定到微信开放平台帐号下后,才会获取UnionID),可通过获取用户基本信息中的UnionID来区分用户的唯一性,
1.获取access_token
公众号可以使用AppID和AppSecret调用本接口来获取access_token;
接口调用:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
2.获知微信服务器的IP地址列表:https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN
自定义菜单
自定义菜单接口可实现多种类型按钮,如下:
1、click:点击推事件
用户点击click类型按钮后,微信服务器会通过消息接口推送消息类型为event 的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
2、view:跳转URL
用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
3、scancode_push:扫码推事件
4、scancode_waitmsg:扫码推事件且弹出“消息接收中”提示框
5、pic_sysphoto:弹出系统拍照发图
6、pic_photo_or_album:弹出拍照或者相册发图
7、pic_weixin:弹出微信相册发图器
8、location_select:弹出地理位置选择器
9、media_id:下发消息(除文本消息)
10、view_limited:跳转图文消息URL
请注意,3到8的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。9和10,是专门给第三方平台旗下未微信认证(具体而言,是资质认证未通过)的订阅号准备的事件类型,它们是没有事件推送的,能力相对受限,其他类型的公众号不必使用。
微信网页授权
如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
1.到公众平台官网中的开发者中心页配置授权回调域名
snsapi_base 只获取到用户的openid
snsapi_userinfo 用来获取用户的基本信息
关于网页授权access_token和普通access_token的区别
1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
2、其他微信接口,需要通过基础支持中的“获取access_token”接口来获取到的普通access_token调用。
网页授权获取用户基本信息也遵循UnionID机制,可通过获取用户基本信息中的unionid来区分用户的唯一性
具体而言,网页授权流程分为四步:
-
- 1 第一步:用户同意授权,获取code
- 2 第二步:通过code换取网页授权access_token
- 3 第三步:刷新access_token(如果需要)
- 4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
- 5 附:检验授权凭证(access_token)是否有效
微信网页授权自我总结:
首先打开OAuth 配置;确定Scopes是snsapi_base还是snsapi_userinfo?
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面) 2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
然后可通过
$wechat = app('wechat');
$oauth = $wechat->oauth;
$wechat_user = $oauth->user();
实例来获取用户信息;从中拿去到对应微信的openid;
亦或者也可通过微信公众平台文档中的接口逐步获取code,access_token等
如果需要微信授权登录的情况下,获取到用户的信息之后可继续逻辑操作。比如:判断用户如果有登录过就直接跳转到网站首页或者个人中心;若未登录需授权登录方可继续下一步操作。
微信JS-SDK说明文档
微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包。网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
JSSDK使用步骤
步骤一:绑定域名
步骤二:引入JS文件
步骤三:通过config接口注入权限验证配置
步骤四:通过ready接口处理成功验证
所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
判断当前客户端版本是否支持指定JS接口
wx.checkJsApi({
jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function(res) {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.onMenuShareAppMessage({ title: '', // 分享标题 desc: '', // 分享描述 link: '', // 分享链接 imgUrl: '', // 分享图标 type: '', // 分享类型,music、video或link,不填默认为link dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空 success: function () { // 用户确认分享后执行的回调函数 }, cancel: function () { // 用户取消分享后执行的回调函数 } });
相关例子:
开发公众号需要用到微信公众平台的服务号,不能是订阅号;因为订阅号可能会对一些权限有限制;从而不能使用到安正超给我们提供的laravel-wechat当中的一些方法和package.
在开发公众号之前我们需要在公众平台的基本配置里面拿到AppId、AppSecret、URL、Token、AESkey.
1.安装包文件:composer require "overtrue/laravel-wechat:~3.0"
2.配置:
(1)注册 ServiceProvider
:
OvertrueLaravelWechatServiceProvider::class,
(2)添加外观到 config/app.php
中的 aliases
部分:
'EasyWeChat' => OvertrueLaravelWechatFacade::class,
(3)创建配置文件:
php artisan vendor:publish
创建成功之后进入到config/wehcat.php文件当中找到appid,secret,token;然后在.env文件中进行配置
然后创建路由:
Route::any('/wechat', 'WechatController@serve');
这里用到any请求的原因是因为是通过get请求验证的,但后面发送消息是通过post请求发送的。
创建控制器WechatController:
<?php
namespace AppHttpControllers; use Log; class WechatController extends Controller { /** * 处理微信的请求消息 * * @return string */ public function serve() { Log::info('request arrived.'); # 注意:Log 为 Laravel 组件,所以它记的日志去 Laravel 日志看,而不是 EasyWeChat 日志 $wechat = app('wechat'); $wechat->server->setMessageHandler(function($message){ return "欢迎关注 overtrue!"; }); Log::info('return response.'); return $wechat->server->serve();//这一句是对微信进行了验证 } }
最后把这一段代码publish到与服务器同步,再对之前公众平台的基本配置进行提交,提交成功之后在接口权限中的网页授权获取用户信息处点击修改;把相对应的域名放上去,如果没有放上去,它的权限也就获取不到。
红包接口调用:
在使用红包请求功能的时候,注意mch_billno(商户订单号)这个参数;
商户订单号(每个订单号必须唯一)
组成: mch_id+yyyymmdd+10位一天内不能重复的数字。
微信支付:
用easywechat来开发微信支付功能,步骤如下:
一,需要有一个商品下单页面,页面上有你的商品的信息,还要有购买数量,和一个购买按钮。
用户在这个页面浏览商品信息的时候,可以选择购买的数量,然后点击提交进入下一个页面。
(这个页面,跟淘宝的商品购买页面一样。)
二,创建一个页面,接收上面一步提交来的数据,然后做如下计算 。
1,根据商品ID或是提交来的商品信息,生成商品的参数数组。
- $product = [
- 'trade_type' => 'JSAPI', // 微信公众号支付填JSAPI
- 'body' => '一盒火柴',
- 'detail' => '一盒火柴',
- 'out_trade_no' => 'MYERPORDERID12345678', // 这是自己ERP系统里的订单ID,不重复就行。
- 'total_fee' => 8888, // 金额,这里的8888分人民币。单位只能是分。
- 'notify_url' => 'http://www.xxx.com/order_notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 (填写发起支付请求的网址)
- 'openid' => 'you-open-id', // 这个不能少,少了要报错。
- // ... 基本上这些参数就够了,或者参考微信文档自行添加删除。
- ];
2,接下来,生成商品对象。
- $order = new Order($product);
3,再接下来,要进行调用前计算了。
- $app = new Application(config('wechat'));
- $payment = $app->payment;
- //统一下单(像公众号支付、扫码支付、APP支付都使用这个接口)
- $result = $payment->prepare($order); // 这里的order是上面一步得来的。 这个prepare()帮你计算了校验码,帮你获取了prepareId.省心。
- //刷卡支付使用下面这个接口:
- //$result = $payment->pay($order);
- $prepayId = null;
- if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
- $prepayId = $result->prepay_id; // 这个很重要。有了这个才能调用支付。
- } else {
- var_dump($result);
- die("出错了。"); // 出错就说出来,不然还能怎样?
- }
- $config = $payment->configForJSSDKPayment($prepayId); // 这个方法是取得js里支付所必须的参数用的。 没这个啥也做不了,除非你自己把js的参数生成一遍
4,就快进入正题,但是,还没完。还要取得一个数据。
- $app = new Application(config('wechat'));
- $js = $app->js; // 这个是jssdk里页面上需要用到的js参数信息。
5,上面获得的$js 和 $config数据,要在页面里显示出来。
注意,上面几步都不涉及显示,只是在生成页面显示所需要的数据。
现在才需要把这些显示在页面上。
- <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript" charset="utf-8"></script>
-
- <script type="text/javascript" charset="utf-8">
- wx.config({{ $js->config(array('chooseWXPay')) }});
- </script>
- <script>
- $(function(){
- $(".btn-do-it").click(function(){
- wx.chooseWXPay({
- timestamp: "{{$config['timestamp']}}", // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
- nonceStr: '{{$config['nonceStr']}}', // 支付签名随机串,不长于 32 位
- package: '{{$config['package']}}', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
- signType: '{{$config['signType']}}', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
- paySign: '{{$config['paySign']}}', // 支付签名
- success: function (res) {
- // 支付成功后的回调函数
- if(res.err_msg == "get_brand_wcpay_request:ok" ) {
- alert('支付成功。');
- window.location.href="{{url("wechat/pay_ok")}}";
- }else{
- //alert(res.errMsg);
- alert("支付失败,请返回重试。");
- }
- },
- fail: function (res) {
- alert("支付失败,请返回重试。");
- }
- });
- });
- });
- </script>
没错,只需要修改这些。
再来理一个,第二步里,这个页面需要显示一个确认信息,比如商品的名称,和支付的总金额。
页面上应该有一个按钮,用来触发支付(.btn-do-it)。
页面里的js就是第5步里要显示的内容。
总结:
第一步,商品信息页面,用户选择购买数据,点购买,提交到第二步的确认页面。
第二步的确认页面,根据商品信息,和微信配置信息,生成必要的支付数据,并显示购买确认信息,和一个支付按钮,
用户点击支付按钮,发起支付。
支付完成,提示用户,或转到相应页面。
微信的开发团队提醒我们,请以微信的推送信息为准来处理订单,不然有可能人财两空。
product.html
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>一盒火柴</title>
- </head>
- <body>
- <h1>一盒火柴</h1>
- <div>
- 卖火柴的小女孩,手里有一堆火柴。
- </div>
- <hr>
- <div>
- <form name="form1" action="payment.php" method="post">
- <lable>数量:</lable>
- <input name="qty" value="1" />
- <input name="submit" type="submit" value="购买" />
- </form>
- </div>
- </body>
- </html>
payment.php
- <?php
- use EasyWeChatFoundationApplication;
- use EasyWeChatPaymentOrder;
- $product = [
- 'body' => '一盒火柴',
- 'trade_type' => 'JSAPI',
- 'out_trade_no' => 'ERP'.time(),
- 'total_fee' => 1,
- 'notify_url' => 'http://test.xxoo.com/wechat/notify/',
- 'openid' => $_SESSION['openid'],
- 'attach' => '卖火柴的小女孩',
- ];
- $order = new Order($product);
- $app = new Application(config('wechat'));
- $js = $app->js;
- $payment = $app->payment;
- $result = $payment->prepare($order);
- $prepayId = null;
- if ($result->return_code == 'SUCCESS' && $result->result_code == 'SUCCESS'){
- $prepayId = $result->prepay_id;
- } else {
- var_dump($result);
- die("出错了。");
- }
- $config = $payment->configForJSSDKPayment($prepayId);
- ?>
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>购买支付</title>
- </head>
- <body>
- <h1>一盒火柴</h1>
- <div>
- <p>您购买了“一盒火柴”,总价格: 0.01元。</p>
- <p>数量:1盒。</p>
- </div>
- <hr>
- <div>
- <input name="button" id="btnPay" type="button" value="支付" />
- </div>
- <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript" charset="utf-8"></script>
- <script type="text/javascript" charset="utf-8">
- wx.config({{ $js->config(array('chooseWXPay')) }});
- </script>
- <script>
- $(function(){
- $(".btn-do-it").click(function(){
- wx.chooseWXPay({
- timestamp: "{{$config['timestamp']}}", // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
- nonceStr: '{{$config['nonceStr']}}', // 支付签名随机串,不长于 32 位
- package: '{{$config['package']}}', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
- signType: '{{$config['signType']}}', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
- paySign: '{{$config['paySign']}}', // 支付签名
- success: function (res) {
- // 支付成功后的回调函数
- if(res.err_msg == "get_brand_wcpay_request:ok" ) {
- alert('支付成功。');
- window.location.href="{{url("wechat/pay_ok")}}";
- }else{
- //alert(res.errMsg);
- alert("支付失败,请返回重试。");
- }
- },
- fail: function (res) {
- alert("支付失败,请返回重试。");
- }
- });
- });
- });
- </script>
- </body>
- </html>
这些是伪代码,payment.php并没有对product.html传来的商品信息做处理。
其实只要看payment.php文件应该知道怎么做了。
其它就两点。a,获取$config,b, 自己写wx.chooseWXPay。
其它的看easywechat文档就行了。
最后
以上就是文静黑米为你收集整理的微信 第三方登录微信网页第三方登录原理的全部内容,希望文章能够帮你解决微信 第三方登录微信网页第三方登录原理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复