之前在项目中遇到网页授权登录这个需求,就对此做些总结记录。
OAuth2.0授权:OAuth是一个开放协议,允许用户让第三方应用以安全且标准的方式获取该用户在某一网站、移动或桌面应用上存储的个人信息,而无需将用户名和密码提供给第三方应用。常见微信、QQ登录,省去管理账户的麻烦,也不会造成用户的流失。
官方手册地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
关于特殊场景下的静默授权:
1、上面已经提到,对于以snsapi_base为scope的网页授权,就静默授权的,用户无感知;
2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知。
网页授权流程分为四步:
1、引导用户进入授权页面同意授权,获取code
GET请求:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
请求示例:https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe0f5948775655753&redirect_uri=http://wjt.cn/Login/wxlogin&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect
![image.png](https://i-blog.csdnimg.cn/blog_migrate/d4fbb0e9f4293e8c49110fbd4fb4474d.png)
如果用户同意授权,页面将跳转至redirect_uri,并且会携带code和state参数
code说明:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
GET请求:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
![image.png](https://i-blog.csdnimg.cn/blog_migrate/f43a9888829e9c8519ff0edc04382f6c.png)
请求成功返回示例
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
// 授权登录示例代码 TP写法
public function wxlogin()
{
// 获取微信返回的code和state
$code = Request::param('code');
$state = Request::param('state');
// 定义appID和appsecret
$appID = "wxe0f5948775655753";
$appsecret = "f9c0007cc2bb709acxxxxxd4a1e";
// 获取token和openid
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appID}&secret={$appsecret}&code={$code}&grant_type=authorization_code";
$arr = json_decode(https_request($url),true); //通过CURL提交GET请求,获取到openid和token并且转为数组
}
3、如果需要,开发者可以刷新网页授权access_token,避免过期
// 获取token
public function getToken(){
// 查询token信息
$tokenList = Db::table("token")->where("id",1)->find();
// 判断数据库中的token是否过期
if($tokenList['time']>time()){
// 如果没过期返回token
$token = "{$tokenList['token']}";
}else{
// 过期了重新获取token
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxe0f59xxxxxx31535&secret=f9c0007cc2bb709ac8xxxxxxx9d4a1e";
$list = https_request($url);
$access = json_decode($list,true);
// 把新的token写入数据库
Db::table("token")->where('id',1)->update(['token'=>$access['access_token'],'time'=>time()+7000]);
// 然后返回token
$token = "{$access['access_token']}";
}
return $token;
}
4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
GET请求:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
![image.png](https://i-blog.csdnimg.cn/blog_migrate/05f1e235f5823c945472edf558cbb8b9.png)
请求成功返回示例
{
"openid": "OPENID",
"nickname": NICKNAME,
"sex": 1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl":"https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"}
// 通过token和openid获取用户信息
$url = " // arr数组见步骤二
$userInfo = json_decode(https_request($url),true); // 用户信息数组