微信开放平台开发——网页微信扫码登录(OAuth2.0)

上一篇文章网站实现微信登录之嵌入二维码中描述了如何在自己的登录页面内嵌入登录二维码,今天的这篇文章主要是描述下在扫码成功之后微信重定向回网站后登录逻辑的处理,其实也就是验证身份信息,授权用户登录的逻辑。这里说句题外话,写博客复习已经做过的项目真的有助于自己对已经写过代码和业务逻辑的理解,说不定还有意外的收获。所谓,“温故而知新”,我会保持写博客的习惯。

1、OAuth2.0

1,微信扫码成功之后

  OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

在用户扫码成功之后,pc端网站上的二维码会出现如下的提示:(这里是用的微信开发文档中的例子1号店网站用来演示效果)。

  允许用户提供一个令牌而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。

图片 1

2、目标

这里需要注意的是,微信开发文档中的例子请求登录1号店网站,它是给出了一个微信登录的链接

  我们这里主要模拟使用OAuth2.0,用户通过扫描我们网页应用的二维码并进行授权登录来获取用户的基本信息的过程。详细的接口相关信息可以在微信开放平台上查看:

header('Location: 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');

3、前期准备(获取微信开发者权限)

在实际开发中,应该根据设计的要求或客户需求来选择利用js嵌入还是在页面中重定向的方法。

  我们这里主要讲的是网站(Web)应用,网站应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统(即上面的协议)。在微信客户端授权登录(获取用户信息)的可以查看:

然后,在手机端的微信中会弹出提示用户确认登陆1号店的界面:

  在进行微信OAuth2.在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的网站应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。

图片 2

3.1、注册开发者账号

点击登录按钮后,pc端网页会跳转到哪儿去呢?这个也要根据实际的业务逻辑来处理。

  可以在 这里申请开发的账号。由于是腾讯的网页,这里可以直接通过 QQ号进行登录。

2,获取access_token和授权用户的openid

3.2、提交网站应用审核

在redirect_uri的URL映射的对应的action中来通过code获取access_token。

  在已经登录的界面中选择“管理中心”——》网站应用——》创建网站应用

 1 public function actionCallback($code, $state) 2 { 3 // 获取并校验前台存储的随机串,防csrf攻击 4 $session = Yii::$app->session; 5 if ($state != $session->get('wx_state')) { 6 exit(); 7 } 8 $session->remove('wx_state'); 9 10 // 微信开放平台网站应用的appid和秘钥secret11 $appid = 'appid';12 $secret = 'secret';13 14 $curl = new Curl();15 $wxresponse = $curl->get('https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid16 . '&secret=' . $secret . '&code=' . $code . '&grant_type=authorization_code');17 $wxresult = json_decode($wxresponse);

图片 3

注意:上面代码第14行用到了一个yii2的curl扩展,感兴趣的可以去github上看下。

   将会弹出下面的界面

第15行请求成功后返回的参数如下:

图片 4

{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN","openid":"OPENID", "scope":"SCOPE" }参数 说明access_token接口调用凭证expires_inaccess_token接口调用凭证超时时间,单位refresh_token用户刷新access_tokenopenid 授权用户唯一标识scope 用户授权的作用域,使用逗号分隔

  填写过后,还有有一个页面需要填写,提交一份纸质版申请书扫描件(会提供模板,我们下载再来填写后,需盖章,签名),配置回调域名(扫码登录后会跳转的页面)等。

actionCallback方法的参数中,$code是用户扫码确认登录后微信返回的,$state是自己设置的参数,详细可见网站实现微信登录之嵌入二维码一文。请求得到access_token和openid最后被存储到$wxresult中。

  之后提交审核即可,等微信审核通过,我们即可获得我们需要的网页应用的appid和AppSecret,并配置后回调的域名了(这三样是我们开发所必须的)。

这里需要注意下,此处返回的openid与第3节中返回的openid是不同的,注意看参数说明。

3.3、开发者资质认证

3,利用上面获取的token和openid获取用户的个人信息,查询数据库验证登录。成功则设置session,不成功,可以考虑添加新用户实现扫码注册的逻辑。

  由于我们这里要使用微信登录的接口,所以我们还需要向微信提出认证,只有认证了才能使用微信那些高级的接口。未认证的如下图所示

 1 if (isset($wxresult->errcode) && $wxresult->errcode > 0) { 2 // 向微信请求授权时出错,打印错误码 3 echo json_encode($wxresult); 4 exit; 5 } else { 6 // 获取用户个人信息 7 $response = $curl->get('https://api.weixin.qq.com/sns/userinfo?access_token=' . $wxresult->access_token 8 . '&openid=' . $wxresult->openid); 9 $result = json_decode($response);10 $wxUser = WxUser::find()->where(['wx_unionid' => $result->unionid])->one();11 if ($wxUser) {12 // 登录13 $result = Yii::$app->user->login($wxUser->id, 3600 * 24 * 30);14 if ($result) {15 // 登录成功,设置session16 Yii::$app->session['wxuser'] = $wxUser->id;17 } else {18 // 登录失败19 echo 'login 失败';20 exit();21 }22 } else {23 // 创建新用户24 }25 }

图片 5

第7行请求成功后,返回的参数示例如下:

   认证之后是这样子的:

{ "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 国家,如中国为CNheadimgurl用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空privilege用户特权信息,json数组,如微信沃卡用户为(chinaunicom)unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。

图片 6

上面代码第10行是依据用户的unionid是否在数据库中来验证其是否为网站的可登录用户,这里为什么要使用用户的unionid呢?这里涉及到了微信授权接口的UnionID机制。

  
 我现在暂时没有找到可以向公众账号那样子的测试账号的申请。如果有知道怎么可以申请到测试账号的高手,希望能赐教一下。

微信开发文档授权后接口调用中对于unionid的解释:此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

  接下来,我们就可以开始我们的网页微信扫码登录开发了。

我的理解是,每个用户对各公众号的OpenID是唯一的,而对于不同公众号,同一用户的openid是不同的。那么如果有多个公众号,用openid就不能区分用户的唯一身份,就只能用unionid了。就算只有一个公众号,也建议采用unionid来区分用户身份的唯一性。

4、授权流程说明

4,小结

  微信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时序图:


 图片 7

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。