Force.com微信开发系列(七)OAuth2.0网页授权
OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站上存储的私密资源(如用户个人信息、照片、视频、联系人列表),而无须将用户名和密码提供给第三方应用。本文将详细介绍OAuth协议以及在微信里的具体实现。
OAuth2.0协议介绍
OAuth2.0是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。 OAuth2.0允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。
OAuth2.0认证和授权的具体过程:
在Oauth2.0认证和授权的过程中涉及的三方包括:
1. 服务提供方,用户使用服务提供方来存储受保护的资源,如照片,视频,联系人列表。
2. 用户,存放在服务提供方的受保护的资源的拥有者。
3. 客户端,要访问服务提供方资源的第三方应用,通常是网站,如提供照片打印服务的网站。在认证过程之前,客户端要向服务提供者申请客户端标识。
使用OAuth进行认证和授权的过程如下所示:
1. 用户访问客户端的网站,想操作用户存放在服务提供方的资源;
2. 客户端向服务提供方请求一个临时令牌;
3. 服务提供方验证客户端的身份后,授予一个临时令牌;
4. 客户端获得临时令牌后,将用户引导至服务提供方的授权页面请求用户授权。在这个过程中将临时令牌和客户端的回调连接发送给服务提供方;
5. 用户在服务提供方的网页上输入用户名和密码,然后授权该客户端访问所请求的资源;
6. 授权成功后,服务提供方引导用户返回客户端的网页;
7. 客户端根据临时令牌从服务提供方那里获取访问令牌;
8. 服务提供方根据临时令牌和用户的授权情况授予客户端访问令牌;
9. 客户端使用获取的访问令牌访问存放在服务提供方上的受保护的资源。
微信网页OAuth2.0授权:
如果用户在微信中(Web微信除外)访问公众号的第三方网页,公众号开发者可以通过此接口获取当前用户基本信息(包括昵称、性别、城市、国家)。利用用户信息,可以实现体验优化、用户来源统计、帐号绑定、用户身份鉴权等功能。
需要注意的是,获取用户基本信息接口(稍后博文会介绍到)是在用户和公众号产生消息交互时,才能根据用户OpenID获取用户基本信息,而网页授权的方式获取用户基本信息,则无需消息交互,只是用户进入到公众号的网页,就可弹出请求用户授权的界面,用户授权后,就可获得其基本信息(此过程甚至不需要用户已经关注公众号。)
下面我们将通过一个具体的例子来展示开发的详细过程。
配置授权回调域名:
在微信公众号请求用户网页授权之前,开发者需要先到公众平台网站的我的服务页中配置授权回调名,需要注意的是这里的域名不要加http://或者https://。另外,授权回调域名配置规范为全域名,比如需要网页授权的域名为: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无法进行OAuth2.0鉴权。
为此进入到服务页(使用正式的服务号或认证后的订阅号后通过我的服务找到,如果是测试账号直接在首页即可找到)后找到OAuth2.0网页授权,点击右侧的修改链接:
在弹出窗口里输入域名后点击确定按钮保存:
用户同意授权,获取Code:
此步骤相当于前面介绍到的OAuth2.0认证过程的第二步“客户端向服务提供方请求一个临时令牌”,这里的Code即是临时令牌,为此可以请求微信的OAuth2.0接口以获取该Code,该接口的参数里需要指定一个回调页面URL,为此我们需要创建一个Apex Page,为此登陆Force.com后找到域名,通常从中国访问的域名是https://ap1.salesforce.com, 在浏览器地址栏中输入https://ap1.salesforce.com/apex/oauth2test, 此时Force.com将提示页面不存在,点击“Create Page oauth2test”链接创建页面:
创建好后的页面如下,如果启用了开发者模式,则页面分为上下两个部分,上部分是显示效果,下面是源代码编辑窗口,默认Force.com会将自身的顶部导航、左侧导航以及CSS样式应用到新创建的页面:
我们通过在第一行里加入以下代码告诉Force.com不要使用默认的CSS样式,不要显示顶部以及左侧的导航栏,同时最后一个controller属性指定了apex页面对应的控制器类,类似于aspx页面对应的aspx.cs类,鼠标保持在编辑栏窗口,按住Ctrl + S组合键即可保存编辑后的代码:
<apex:page standardstylesheets="false" showHeader="false" sidebar="false" controller="oauth2testcontroller">
此时,应为对应的oauth2testcontroller类并不存在,浏览器会报以下错误:
这里点击第二个链接“Create Apex class ‘public class oauth2testcontroller’”自动创建控制器类。留意这两个链接的唯一区别在于”with sharing”关键字,这个关键字指定了当前类对各个对对象(相当于数据表)、字段等的访问权限与当前登录用户同,如果不指定,Apex页面将拥有对所有对象、字段的访问权限。创建好后在下方代码编辑栏中将多出一个控制器类Tab:
在该类中添加代码如下:
public class oauth2testcontroller {
public String code {get; set;}
public oauth2testcontroller(){
code = ApexPages.currentPage().getParameters().get('code');
if(String.isBlank(code)){
code = 'No Code';
}
}
}
这段代码中第2行定义了一个公开属性code,第4行通过ApexPages对象获得URL中的code参数,并接着判断是否code值是否为空,如果为空则提示No Code。下面我们会看到微信授权成功回调此URL时会将code参数添加到URL中。
接下来略微修改前台页面,在页面中显示得到的code值:
<apex:page standardstylesheets="false" showHeader="false" sidebar="false" controller="oauth2testcontroller">
{!code}
</apex:page>
{!对象名}是Force.com Visualforce page里用来显示对象值的语法,接下来我们需要配置该页面能够通过公网进行访问,为此登陆Force.com后,进入Setup –> Develop –> Sites,点击站点对应的Site Label标签如下图:
进入详细配置页面后找到“Site Visualforce Page”,点击右侧的Edit按钮:
找到左侧列表中的oauth2test页面添加到右侧,并保存修改:
此时即可通过http://johnson0001-developer-edition.ap1.force.com/oauth2test公网地址来访问前面创造的页面了。接下来我们可以利用微信平台的OAuth2认证接口组拼URL并引导用户通过微信来访问,该接口的格式如下:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限,其中每个参数的详细说明如下:
在我们的例子里URL如下,其中scope我们指定为snsapi_userinfo,弹出授权页面:
兴许是测试账号的关系,虽然微信接口文档里提到在制定scope为snsapi_userinfo的情况下会弹出如下图左所示的授权页面,但反复尝试(乃至删除并重新关注账号)中也没有看到该页面,不过重点是我们得到了临时令牌,如下图右所示。右图实际是http://johnson0001-developer-edition.ap1.force.com/oauth2test页面,用户同意授权后跳转到(或者我遇到的实际情况是直接跳转)到redirect_uri/?CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE。
另外特别需要说明的是,code作为换取access_token的临时票据,每次用户授权带上的code都不一样,code只能使用一次,5分钟未被使用自动过期。
通过Code换取网页授权access_token:
首先请注意,这里通过code换取的网页授权access_token,与基础支持中的access_token不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了 openid,snsapi_base式的网页授权流程即到此为止。 获取code后,可以通过以下接口获取access_token:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
这里的CODE即为通过前面方式获得的临时令牌(票据),参数的具体说明如下:
将URL直接输入到浏览器地址栏即可得到返回数据,当然真实场景里更多通过后台代码来请求,正确返回时的JSON数据包如下:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数的具体说明如下:
错误时微信会返回JSON数据包如下(示例为Code无效错误):
{"errcode":40029,"errmsg":"invalid code"}
在本例中获得的access_token实例如下:
{"access_token":"OezXcEiiBSKSxW0eoylIeMEUA_AZuBDY8AO0IIw270MMsvemqLvgx1HqemeXIZfzXW2d6yHCPy9cA1yHZ1jHCkwlH5Ct5Jfa1jOQm88M9LzU_O8BCKMNhN7yLlHJfOFLuf4lLTNGOOsoWYxQzYVNGw","expires_in":7200,"refresh_token":"OezXcEiiBSKSxW0eoylIeMEUA_AZuBDY8AO0IIw270MMsvemqLvgx1HqemeXIZfz_Vj5pJZlv2V5wK9EzWmxQmM07cqIAwMXOdqzlQs-NY4hiyENP4WhO4Twpko-3iY_pAPZRnGGmAVt3DirZaWIyg","openid":"ou-37t936RNZEcW0mI75RN2pdxkc","scope":"snsapi_userinfo"}
可以看到上面access_token的默认失效时间是7200秒,也就是2小时,当access_token超时后,可以通过refresh_token进行刷新,refresh_token拥有较长的有效期(7天、30天、60天、90天),当refresh_token失效后,需要用户重新授权,简化理解起见,我们在本文的最后再介绍相关技术。
拉取用户信息(需Scope为snasapi_userinfo):
通过access_token获取用户信息的接口如下,使用GET方法:
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
参数具体说明如下:
本例的URL如下:
输入浏览器访问即可得到相应的用户信息:
{"openid":"ou-37t936RNZEcW0mI75RN2pdxkc","nickname":"王浩","sex":1,"language":"zh_CN","city":"松江","province":"上海","country":"中国","headimgurl":"http:\/\/wx.qlogo.cn\/mmopen\/lqsZNvDqcXe8nBKHBPsp9YHuZXPtkzOD1uq3r3xxDicuDLKGlicNd1b371ODnn9xNBB9y9ChBSfL7tuX6m9FS8koY9Ex1iaJRDI\/0","privilege":[]}
刷新access_token:
可以通过前面在“通过Code换取网页授权access_token”小节中获得的refresh_token来调用刷新Token接口获取更新的access_token,微信在API文档里介绍refresh_token拥有较长的有效期(7天、30天、60天、90天),但实际微信的refresh_token的有效期是多长没有具体说明,如果有具体经验的朋友欢迎分享。微信刷新access_token的接口如下:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
接口的具体参数定义如下:
正确时返回的JSON数据包如下:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
数据包的具体定义如下:
错误时微信会返回JSON数据包如下(示例为Code无效错误):
{"errcode":40029,"errmsg":"invalid code"}
Force.com微信开发系列(七)OAuth2.0网页授权的更多相关文章
- 微信公众号开发(5)---使用开源组件开发公众号OAuth2.0网页授权授权登录
搞清微信公众号授权登录的步骤步骤,我们的开发就完成了一大步 献上github 地址: https://github.com/Wechat-Group/weixin-java-tools/wiki/MP ...
- 用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面
现在很流行微信网页小游戏,用html5制作的小游戏移过来,可以放到微信浏览器中打开,关键是可以做成微信分享朋友圈的形式,大大提高游戏的传播,增强好友的游戏互动. 微信浏览器中打开网页游戏效果还不错,对 ...
- [转]用chrome模拟微信浏览器访问需要OAuth2.0网页授权的页面
FROM : http://blog.csdn.net/gavin_luo/article/details/40620217 现在很流行微信网页小游戏,用html5制作的小游戏移过来,可以放到微信浏览 ...
- 微信公众平台开发(71)OAuth2.0网页授权
微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友在使 ...
- Force.com微信开发系列(五)自定义菜单进阶及语音识别
在上文里我们介绍了如何通过Force.com平台里为微信账号添加自定义菜单,本文里我们将进一步介绍如何查询菜单以及删除菜单的相关知识,最后会介绍微信平台如何进行语音识别的相关技术. 查询菜单 与创建菜 ...
- Force.com微信开发系列(三)申请测试账号及回复图文消息
Force.com除了简单的文本消息回复外,还能回复图文并茂的消息.能回复音乐或者视频.能对用户发来的语音进行识别.能够搜集用户的地理位置信息并提供相应的内容或服务等,本文将对这些技能一一展开说明,在 ...
- 微信公众平台开发(71)OAuth2.0网页授权-摘抄
微信公众平台开发 OAuth2.0网页授权认证 网页授权获取用户基本信息 作者:方倍工作室 微信公众平台最近新推出微信认证,认证后可以获得高级接口权限,其中一个是OAuth2.0网页授权,很多朋友 ...
- ***微信公众平台开发: 获取用户基本信息+OAuth2.0网页授权
本文介绍如何获得微信公众平台关注用户的基本信息,包括昵称.头像.性别.国家.省份.城市.语言.本文的方法将囊括订阅号和服务号以及自定义菜单各种场景,无论是否有高级接口权限,都有办法来获得用户基本信息, ...
- 微信公众平台开发-OAuth2.0网页授权(含源码)
微信公众平台开发-OAuth2.0网页授权接口.网页授权接口详解(含源码)作者: 孟祥磊-<微信公众平台开发实例教程> 在微信开发的高级应用中,几乎都会使用到该接口,因为通过该接口,可以获 ...
随机推荐
- python高效解析日志入库
python脚本解析日志文件入库一般有三个重要的步骤:读文件.解析文件.入库.在这三个方面下功夫,可确保我们获得最优的性能(这里不讨论并发) 1 读文件:一次读一行,磁盘IO太多,效率低下:一次性读如 ...
- SQL数据类型解释
SQL数据类型解释 1.char.varchar.text.ntext.bigint.int.smallint.tinyint和bit的区别及数据库的数据类型电脑秘籍 2009-05-15 21:47 ...
- Sql触发器模板
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程. 触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. SQL Server 2005中触发器可以分 ...
- 未在本地计算机上注册 Microsoft.Jet.OLEDB.4.0 提供程序
在C#的web程序中读取服务器端的Excel文件时所报的异常 问题描述:在Visual Studio中运行.调试均没有问题,但是部署到Windows Server 2008 64位操作系统的IIS7 ...
- JavaScript之Array常用函数汇总
[20141121]JavaScript之Array常用功能汇总 *:first-child { margin-top: 0 !important; } body>*:last-child { ...
- 斐波那契堆(一)之 图文解析 和 C语言的实现
概要 本章介绍斐波那契堆.和以往一样,本文会先对斐波那契堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现:实现的语言虽不同,但是原理如出一辙,选择其中之一进行了 ...
- 后缀数组 --- WOj 1564 Problem 1564 - A - Circle
Problem 1564 - A - Circle Problem's Link: http://acm.whu.edu.cn/land/problem/detail?problem_id=156 ...
- 三分 --- POJ 3301 Texas Trip
Texas Trip Problem's Link: http://poj.org/problem?id=3301 Mean: 给定n(n <= 30)个点,求出包含这些点的面积最小的正方形 ...
- 分享一下学习css,js心得
简化代码,使页面简洁! web前端开发——将界面更好呈现给用户! 要了解在不同浏览器上的兼容情况.渲染原理和存在的bug! 网站性能优化.SEO: 代码的可维护性.性能: 网站重构的本质:建立一个前端 ...
- ASP.NET MVC4 数据库连接(EF6.0)
我的博客原文地址:http://www.star110.com/Note/ReadArticle/60641215331146140041.html 环境:.NET MVC4 + EF6.0 连接数据 ...