OAuth2.0实战之微信授权篇
微信开发三大坑:
- 微信OAuth2.0授权
- 微信jssdk签名
- 微信支付签名
本篇先搞定微信OAuth2.0授权吧!
以简书的登陆页面为例,来了解一下oauth2.0验证授权的一些背景知识:
1) 传统的注册登陆方式:
如果你是一个新用户,则点击新用户注册按钮,进入由简书提供的注册页面,进行用户名密码验证和设置
然后再回到简书提供的登陆页面,输入刚注册的用户名和密码进行登陆
缺点(站在用户的角度):
除非我很想使用该app,否则根本不想花这么多时间进行注册,太麻烦了。
如果使用app很多,到处注册,密码要么一样,要么多到你记不住
- 每次登陆还要手动输入用户名以及密码,也是很麻烦的事情
优点(站在app提供者的角度):
- 对app提供者来说,新客户注册对其吸引投资,增加市值,加强影响力是有非常大的帮助。
那么有什么好的方法,能够避免掉用户注册登陆的不便之处呢?
答案就是: 利用各个社交app(例如微信)现有的注册账号进行第三方(例如简书)应用的验证授权登陆,这就是传说中的oauth2.0授权登陆。
之所以使用社交软件账号是因为用户实在是够多啊!作为国人,大家基本上都有微信,qq等账号。这样就只要点击一下简书登陆页面中的社交账号直接登陆中某个图标就直接进入由社交app提供的授权页面
2) oauth2.0授权登陆:
上图显示了简书使用微信/qq/豆瓣/新浪微博进行oauth2.0授权登陆的界面,该界面并不是由简书提供的,而是由对应的各个社交app提供的
上面四个界面中,微信登陆只要按确认登陆就能登陆简书app(不要注册,不要填写用户名+密码,只要点击确认登陆就能登陆简书。甚至可以通过静默授权,连这个页面都不需要显示就直接进入简书)。
其他的三个界面还是需要输入对应社交app的用户名+密码。这是因为我只打开了微信app,qq没开,至于豆瓣以及新浪微博,我还没有账号。
3) 以简书为例子,来简单说明oauth2.0授权登陆流程:
什么是oatuh2.0协议:
OAuth2.0(开放授权)是一个开放标准。
没啥好解释的,就是一个标准允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息。
蕴含很多信息哦!
这句话提到了三个角色:第三方网站/用户/服务商
这句话是站在服务商的角度进行描述的。
服务商:以微信为例子,那么服务商就是微信[服务器]或腾讯
用户 : 就是你,你的相关信息(例如用户名/密码/性别/ 省份等等等等)都是存放在服务商的服务器中。注意:你不是第三方(例如简书)的用户,而是微信的用户(因为你是注册在微信中,而不是简书中)
第三方网站 : 这里指的就是简书[服务器]而这种授权无需将用户提供用户名和密码提供给该第三方网站。
这句话的意思很明显,就是简书服务器是没法拿到你在微信服务器中的用户名和密码的,但是的确能够让你登陆简书服务器- 既然第三方(简书)无法拿到你的用户名和密码,那肯定是由服务商(微信)来进行验证,那么第三方肯定要和服务商有一种机制来进行辨识:
在认证过程之前,第三方(简书)需要先向服务商(微信)申请第三方(简书)服务的唯一标识
因此第三方(简书)填写本公司相关信息,提供本公司账号,域名等信息,并且花三百块钱给服务商(腾讯)进行审核。服务商腾讯收到钱,并且审核通过后,会给第三方(简书)两个编号:AppID和appSecret(及其重要,不能泄露)。通过这两个编号,就能确认唯一性了。当然过程是很复杂的。
- 第三方[服务器]和服务商[服务器]之间的通信:
既然第三方(简书)用通过服务商(微信)来验证用户(你)身份的合法性,那么肯定涉及到:一旦服务商(微信)确认用户(你)的合法身份后,如何将信息传递给第三方(简书)
很简单,通过第三方(简书服务器)提供的回调URL,服务商(微信服务器)将相关数据以参数形式写入到第三方(简书服务器)提供的回调URL,第三方(简书服务器)解析服务商(微信服务器)发过来的信息抽取出来就OK了!
那在微信公众号的申请中,有要求第三方(简书)提供回调地址
oauth2.0授权流程:
其中:
2--7步骤是通过简书调用:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
这个API进行的,具体参数请参见文档说明
8-9步骤是通过简书调用:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
这个API进行的,具体参数请参见文档说明
步骤10以后,是通过accesstoken以及openid等从微信获取相关信息了
由于微信的开发需要审批,独立的域名(不能使用localhost),并且要求是80端口(http)或443端口(https),这独立域名以及这两个端口需要工信部审批后才可使用,因此我这里目前没有这种开发环境,但是我可以提供一段代码,以前分享在群里面,用于进行微信oauth2.0授权,我以前可以获取正确的结果,目前应该也可以。
只是例子而已,不要使用在生产环境:
由于使用nodejs的wechat-oauth库进行微信oauth2.0授权操作
因此可以先npm install wechat-oauth --save下载到你的开发包中去
顺便说一下,wechat-oauth是由深入浅出nodejs作者朴灵撰写的库
通过微信授权获取openid和accesstoken示例代码:
//1、引入wechat-oauth包
var OAuth = require('wechat-oauth');
//2、生成一个OAuth的实例,appId和appSecert作为构造参数
var oauthApi = new OAuth(你的appId, 你的appSecert);
//3、构造一个路由,用于获取微信写入到你的回调url中的code数据
//这个路由就是你注册在微信开发中的回调url!!!!
//此时的你充当的是第三方网站角色,相当于简书服务器
app.get('/callback', function (req, res) {
console.log('----weixin callback -----')
var code = req.query.code;
console.log("code =" + code);
//通过code获取accesstoken
oauthApi.getAccessToken(code, function (err, result){
//如果函数调用成功,会在result中得到access_token
var accessToken = result.data.access_token;
//以及openid;
var openid = result.data.openid;
console.log('openid='+ openid);
//然后通过openid获取用户信息
oauthApi.getUser(openid, function (err, result1) {
console.log('use weixin api get user: ' + err)
console.log(result)
var oauth_user = result1;
//打印出用户信息
console.log("userinfo" + JSON.stringify(oauth_user, null, ' '));
//授权成功获取信息后,重定向到你要去的页面
//这里随便,所以直接重定向到首页了,你可以换成其他任何页面
res.redirect('/');
});
console.log("blf write" + JSON.stringify(result.data, null, ' '));
});
});
//url就是3、中定义的路由一致,用来接收微信发过来的code
//关键点: callbackURL必须要和3、中定义的路由一致!!!
// 且callbackURL就是你在微信中提供的回调url!!!
//就是上图显示的url!!!
var callbackURL = 'http://你的域名/callback';
//oauth2是你定义的路由,当你点击微信登陆这个按钮时,就调用oauth2这个路由,向腾讯请求oauth2授权验证
//腾讯验证通过,会将code写入到3、这个回调url中
//然后通过3、路由,获取code, 换取accesstoken以及openid
//再通过openid获取userInfo,漂亮,完成整个操作
app.get('/oauth2', function(req, res) {
var url = oauthApi.getAuthorizeURL(callbackURL,'','snsapi_base');
console.log(url);
//重定向的回调地址,获取code,通过code换取openid和accesstoken ,通过openid获取用户信息
//所有一起如此简单
res.redirect(url);
})
用到了wechat-oauth库中的三个api:
oauthApi.getAuthorizeURL
相当于2--7步骤是通过调用:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
还是贴一下该函数的源码吧,这样就清晰了
/**
* 获取授权页面的URL地址
* @param {String} redirect 授权后要跳转的地址
* @param {String} state 开发者可提供的数据
* @param {String} scope 作用范围,值为snsapi_userinfo和snsapi_base,前者用于弹出,后者用于跳转
*/
OAuth.prototype.getAuthorizeURL = function (redirect, state, scope) {
var url = 'https://open.weixin.qq.com/connect/oauth2/authorize';
var info = {
appid: this.appid,
redirect_uri: redirect,
response_type: 'code',
scope: scope || 'snsapi_base',
state: state || ''
};
//合成授权请求url
//然后第三方网站(你)重定向到这个url中去
//其结果就是调用callback路由
//于是就运行你在callback中的代码了
//流程衔接起来了
return url + '?' + querystring.stringify(info) + '#wechat_redirect';
};
oauthApi.getAccessToken
相当于8-9步骤是通过调用:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
OAuth.prototype.getAccessToken = function (code, callback) {
var url = 'https://api.weixin.qq.com/sns/oauth2/access_token';
var info = {
appid: this.appid,
secret: this.appsecret,
code: code,
grant_type: 'authorization_code'
};
var args = {
data: info,
dataType: 'json'
};
//请求url,通过code换取accesstoken,openid等等
this.request(url, args, wrapper(processToken(this, callback)));
};
oauthApi.getUser
相当于步骤10以后,是通过accesstoken以及openid等从微信获取相关信息了
上面的代码可以直接用于微信公众号授权,希望对大家有帮助
4) 下一步计划:
由于微信的授权我这里没有环境(其实国内的环境导致都需要独立域名以及80/443端口问题),因此想实现一个类似腾讯的oauth2.0授权服务器。目前完成70%,还有一些问题需要解决。
使用了node-oauth2-server库开发oauth2.0服务器,但是登陆验证的话,要使用passport,需要自己写一个passport-strategy插件,这个有点麻烦。目前我需要向前推进,所以自己的oauth2.0授权和passport验证放在以后实现。
其实我的需求如下:
1、使用IBM loopback库实现服务器
2、可以使用localhost:非80端口 进行oauth2.0授权回调,不需要独立域名以及80/443端口(这个需要工信部审批,很麻烦的)
3、国内可以进行访问,不需要那个啥(facebook/google可以使用localhost,并且非80/443端口,但是不那个啥就没法访问)
通过实验,突然发现一个满足上述所有要求的网站:
伟大的github,可以使用github开发账户,以localhost方式接受github发送过来的code,换取accesstoken等,进行oatuh2.0授权。
下一步我们就实战,通过本地调用来实现github oauth2.0授权。
我们会使用loopback库以及loopback-component-passport插件来演示一个Demo,大家会看到根本需要写一句代码,就能完美的进行oauth2.0授权!
IBM loopback非常好用,我会用loopback实现一个完整的服务器,与大家分享。
作为oauth2.0最后一部,我会使用node-oauth2-server以及passport实现自己的oauth2.0服务器,与大家分享实现的过程,以及node-oauth2-server(上个礼拜已经注释好了)和passport(曾经读过源码,但是是去年,可能需要回忆一下,哈哈)的源码分析
使用loopback-component-passport插件实现github和facebook登陆成功的图片:
github
facebook:
作者:
链接:https://www.imooc.com/article/17696
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
OAuth2.0实战之微信授权篇的更多相关文章
- 没错,用三方 Github 做授权登录就是这么简单!(OAuth2.0实战)
本文收录在个人博客:www.chengxy-nds.top,技术资源共享. 上一篇<OAuth2.0 的四种授权方式>文末说过,后续要来一波OAuth2.0实战,耽误了几天今儿终于补上了. ...
- OAuth2.0实战:认证、资源服务异常自定义!
大家好,我是不才陈某~ 这是<Spring Security 进阶>的第4篇文章,往期文章如下: 实战!Spring Boot Security+JWT前后端分离架构登录认证! 妹子始终没 ...
- OAuth2.0的四种授权模式
1.什么是OAuth2 OAuth(开放授权)是一个开放标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容,OA ...
- OAuth2.0实战!使用JWT令牌认证!
大家好,我是不才陈某~ 这是<Spring Security 进阶>的第3篇文章,往期文章如下: 实战!Spring Boot Security+JWT前后端分离架构登录认证! 妹子始终没 ...
- OAuth2.0的四种授权模式(转)
1. OAuth2简易实战(一)-四种模式 1.1. 隐式授权模式(Implicit Grant) 第一步:用户访问页面时,重定向到认证服务器. 第二步:认证服务器给用户一个认证页面,等待用户授权. ...
- iOS OAuth2.0认证和SSO授权
OAuth2.0和SSO授权 一.OAuth2.0授权协议 一种安全的登陆协议,用户提交的账户密码不提交到本APP,而是提交到授权服务器,待服务器确认后,返回本APP一个访问令牌,本APP即可用该 ...
- OAuth2.0授权和SSO授权
一. OAuth2.0授权和SSO授 1. OAuth2.0 --> 网页 --> 当前程序内授权 --> 输入账号密码 --> (自己需要获取到令牌, 自己处理逻辑) 授权成 ...
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-4.微信授权一键登录开发之授权URL获取
笔记 4.微信授权一键登录开发之授权URL获取 简介:获取微信开放平台扫码连url地址 1.增加结果工具类,JsonData; 增加application.properties配置 ...
- oauth2.0+app方式 webgis 授权
.认证方式有三种 Oauth2.0, Token-based http/windows 二.用户登录与应用登录区别 两者区别在于:当用户登录时,服务器端平台是否直接识别登录信息和验证登录信息. 应用登 ...
随机推荐
- webkit-user-select:none 问题
webkit-user-select:none 问题 学习了:https://bugs.webkit.org/show_bug.cgi?id=82692 最近两天做移动端游戏举报页面.遇到一个问题,移 ...
- ExtMail telnet 25端口号 不通
搭建好的Mail服务器在本地端口号25是开的,但是在别的电脑上就连不上. 修改/etc/postfix/main.cf文件,将 inet_interfaces = localhost 注释掉即可.
- 报错信息:The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
用Eclipse创建jsp页面时,提示这个错误 解决的方法是:右键项目,Build Path->Configure Build Path Add Library Server Runtime,这 ...
- jQuery.cookie应用操作
//1.插件框架: /* * name @键 * value @值 * options @选项,包括有效期 路径 域名等 */ jQuery.cookie = function(name, value ...
- ZH奶酪:Python按行读取文件
1:readline() file = open("sample.txt") while 1: line = file.readline() if not line: break ...
- linux加入windows域
http://www.redhat.com/rhecm/rest-rhecm/jcr/repository/collaboration/jcr:system/jcr:versionStorage/36 ...
- C#中使用RabbitMQ收发队列消息
一.程序使用NetCore.引入Nuget: Install-Package RabbitMQ.Client -Version 4.1.3 二.消息发部端: using RabbitMQ.Client ...
- 015-Go 数据库操作注意事项
1.Query.Exec(1)Exec(update.insert.delete等无结果集返回的操作)调用完后会自动释放连接:(2)Query(返回sql.Rows)则不会释放连接,调用完后仍然占有连 ...
- phpstudy部署thinkPHP
利用phpstudy配置虚拟主机 Listen 8080 <VirtualHost _default_:80> DocumentRoot "D:\phpStudy\WWW&quo ...
- stingray前端架构总体设计及运行过程
SPA 单页应用程序,在一个页面内用ajax技术实现所有的功能的web程序,我们称之为单页应用,明显的特点就是第一次加载之后地址栏非参数部分不再发生变化.大家观察会发现 WIP系统就是一个SPA.我们 ...