我们在逛一些需要登录的网站时,经常可以看到各种各样的登录方式,有最常见的注册账号登录、有最近流行的扫描二维码登录、还有使用第三方账号登录(如用QQ号一键登录)等。
今天我们来聊一聊"使用百度账号登录"功能的实现。
(其实本来想写使用QQ登录功能的实现的,无奈腾讯互联的申请实在是太麻烦了,申请了几次都没过,只好暂时作罢)
准备活动
首先,需要登录百度开发者中心,点击应用管理》创建工程。我这里将工程名字命名为“孟坤软件”,勾选“传统接入扩展选”。如下图所示:
创建完后我们便可以得到所需要的API Key和Secret Key。在“基本信息”栏里我们可以修改应用的图标。
完成上一步后,我们再点击左侧的安全设置,在“根域名绑定”里填写你的根域名(比如我的是 mkblog.cn,不要http://www之类的前缀)。在“应用服务器IP地址”里填写你的网站的IP地址。其余的设置不用更改。点击“确定”保存,完成后应该是这样的:
到这里,准备活动就做完了!
开始接入
通过百度的开发帮助文档,可以了解到授权的方式有Authorization Code、Implicit Grant、Client Credentials、Device几种。我们选择适合网页端的Authorization Code,通过它我们可以得到一个有效期一个月的Access Token和有效期十年的Refresh Token。
Authorization Code需要向“https://openapi.baidu.com/oauth/2.0/authorize”请求如下数据:
- client_id:必须参数,注册应用时获得的API Key。
- response_type:必须参数,此值固定为“code”。
- redirect_uri:必须参数,授权后要回调的URI。
- scope:非必须参数,以空格分隔的权限列表。
- state:非必须参数,用于保持请求和回调的状态。
- display:非必须参数,登录和授权页面的展现样式。
- force_login:非必须参数,如传递“force_login=1”,则加载登录页时强制用户输入用户名和口令,不会从cookie中读取百度用户的登陆状态。
- confirm_login:非必须参数,如传递“confirm_login=1”且百度用户已处于登陆状态,会提示是否使用已当前登陆用户对应用授权。
- login_type:非必须参数,如传递“login_type=sms”,授权页面会默认使用短信动态密码注册登陆方式。
这些请求如何使用呢?我们可以新建一个php页面,命名为baidu.php,代码如下:
- <?php
- $url = 'https://openapi.baidu.com/oauth/2.0/authorize?'; //请求地址
- $url .='&response_type=code'; //固定值
- $url .= '&client_id=xxxxxxxx'; //这里后面跟的是应用的API Key
- $url .= '&redirect_uri=http://www.demo.com/callback.php'; //根据你的需要,设置的登录成功后的回调地址(回掉数据处理稍后再讲)
- $url .= '&confirm_login=1'; //优先已登录的账号
- $url .= '&display=popup'; //弹窗的方式出现
- header("Location: $url");
把这个php上传到服务器,打开它就会跳转到百度登录的界面:
我们点击下面的“授权”(登录)就会跳转到之前的 redirect_uri 这个参数设定的URL,并且后面还多了个“?code=xxxxxx”。那么恭喜你,到这一步就已经成功一半了!
数据的处理
我们再创建一个php文件,命名为 callback.php ,用于处理响应数据。
直接在 callback.php 里添加以下代码就能获取返回的 code。
- <?php
- if(isset($_GET['error']))
- {
- $error = $_GET['error'];
- if($error == 'access_denied') //这个错误是因为用户中止了授权操作引起的
- die('用户取消了授权');
- }
- if(isset($_GET['code']))
- {
- $code = $_GET['code']; //获取到返回的 Authorization Code
- }
- else
- {
- die('参数错误');
- }
获取到了Authorization Code就可以用它来请求最终的Access Token了,Access Token需要向‘https://openapi.baidu.com/oauth/2.0/token’请求数据如下:
- grant_type:必须参数,此值固定为“authorization_code”;
- code:必须参数,通过上面第一步所获得的Authorization Code;
- client_id:必须参数,应用的API Key;
- client_secret:必须参数,'应用的Secret Key;
- redirect_uri:必须参数,该值必须与获取Authorization Code时传递的“redirect_uri”保持一致。
具体的代码实现如下(接着上面的代码来)
- $url = 'https://openapi.baidu.com/oauth/2.0/token'; //请求地址
- $data = array('grant_type'=>'authorization_code',
- 'code'=>$code,
- 'client_id'=>'xxxxxx', //应用的API Key
- 'client_secret'=>'xxxxxx', //应用的Secret Key
- 'redirect_uri'=>'http://www.demo.com/callback.php'); //这里要与之前的回调地址保持一直
- $header = array();
- $response = curl_https($url, $data, $header, 5);
- $obj=json_decode($response);
- if(isset($obj->error))
- {
- echo '与百度账号连接过程中出错:'.$obj->error.'。错误详细内容:'.$obj->error_description;
- }else{
- if(isset($obj->expires_in)) echo 'expires_in:'.$obj->expires_in."<br>";
- if(isset($obj->refresh_token)) echo 'refresh_token:'.$obj->refresh_token."<br>";
- if(isset($obj->access_token)) echo 'access_token:'.$obj->access_token."<br>";
- if(isset($obj->session_secret)) echo 'session_secret:'.$obj->session_secret."<br>";
- if(isset($obj->session_key)) echo 'session_key:'.$obj->session_key."<br>";
- if(isset($obj->scope)) echo 'scope:'.$obj->scope."<br>";
- }
(注:这里的“curl_https”函数请参照php使用curl访问https示例这篇博文)
这样,我们就获得了最终的token,获取到了token之后的进一步操作可以参照相关的 api文档
附录:
Oauth api大全:http://developer.baidu.com/wiki/index.php?title=docs/oauth/rest/file_data_apis_list
本文作者为mengkun,转载请注明。
我用device授权,总是返回如下信息
read:286
headlen:286
READ:HTTP/1.1 302 Found
Content-Type: text/html
Date: Thu, 14 Sep 2017 02:37:04 GMT
Location: https://openapi.baidu.com/oauth/2.0/device/code?client_id=nou9TtG7BHW7KKEGxU6ykrPXpjHQyEA6&response_type=device_code&scope=basic,netdisk
Server: Apache
Content-Length: 0
Connection: close
这是为什么?
@bingo不清楚……很久没研究这个 Api 了
@mengkun谢谢