“使用百度账号登录”功能的实现

mengkun 6K 3

我们在逛一些需要登录的网站时,经常可以看到各种各样的登录方式,有最常见的注册账号登录、有最近流行的扫描二维码登录、还有使用第三方账号登录(如用QQ号一键登录)等。

今天我们来聊一聊"使用百度账号登录"功能的实现。
(其实本来想写使用QQ登录功能的实现的,无奈腾讯互联的申请实在是太麻烦了,申请了几次都没过,只好暂时作罢)

准备活动

首先,需要登录百度开发者中心,点击应用管理》创建工程。我这里将工程名字命名为“孟坤软件”,勾选“传统接入扩展选”。如下图所示:

创建完后我们便可以得到所需要的API Key和Secret Key。在“基本信息”栏里我们可以修改应用的图标。

完成上一步后,我们再点击左侧的安全设置,在“根域名绑定”里填写你的根域名(比如我的是 mkblog.cn,不要http://www之类的前缀)。在“应用服务器IP地址”里填写你的网站的IP地址。其余的设置不用更改。点击“确定”保存,完成后应该是这样的:

到这里,准备活动就做完了!

开始接入

通过百度的开发帮助文档,可以了解到授权的方式有Authorization CodeImplicit GrantClient CredentialsDevice几种。我们选择适合网页端的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,代码如下:

  1. <?php
  2. $url = 'https://openapi.baidu.com/oauth/2.0/authorize?';   //请求地址
  3. $url .='&response_type=code';   //固定值
  4. $url .= '&client_id=xxxxxxxx';  //这里后面跟的是应用的API Key
  5. $url .= '&redirect_uri=http://www.demo.com/callback.php'; //根据你的需要,设置的登录成功后的回调地址(回掉数据处理稍后再讲)
  6. $url .= '&confirm_login=1'; //优先已登录的账号
  7. $url .= '&display=popup';   //弹窗的方式出现
  8. header("Location: $url");

把这个php上传到服务器,打开它就会跳转到百度登录的界面:

我们点击下面的“授权”(登录)就会跳转到之前的 redirect_uri 这个参数设定的URL,并且后面还多了个“?code=xxxxxx”。那么恭喜你,到这一步就已经成功一半了!

数据的处理

我们再创建一个php文件,命名为 callback.php ,用于处理响应数据
直接在 callback.php 里添加以下代码就能获取返回的 code。

  1. <?php
  2. if(isset($_GET['error']))
  3. {
  4.     $error = $_GET['error'];
  5.     if($error == 'access_denied')   //这个错误是因为用户中止了授权操作引起的
  6.         die('用户取消了授权');
  7. }
  8. if(isset($_GET['code']))
  9. {
  10.     $code = $_GET['code'];  //获取到返回的 Authorization Code
  11. }
  12. else
  13. {
  14.     die('参数错误');
  15. }

获取到了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”保持一致。

 

具体的代码实现如下(接着上面的代码来)

  1. $url = 'https://openapi.baidu.com/oauth/2.0/token'; //请求地址
  2. $data = array('grant_type'=>'authorization_code',
  3.               'code'=>$code,
  4.               'client_id'=>'xxxxxx',    //应用的API Key
  5.               'client_secret'=>'xxxxxx',    //应用的Secret Key
  6.               'redirect_uri'=>'http://www.demo.com/callback.php'); //这里要与之前的回调地址保持一直
  7. $header = array();
  8. $response = curl_https($url$data$header, 5);
  9. $obj=json_decode($response);
  10. if(isset($obj->error))
  11. {
  12.     echo '与百度账号连接过程中出错:'.$obj->error.'。错误详细内容:'.$obj->error_description;
  13. }else{
  14.     if(isset($obj->expires_in)) echo 'expires_in:'.$obj->expires_in."<br>";
  15.     if(isset($obj->refresh_token)) echo 'refresh_token:'.$obj->refresh_token."<br>";
  16.     if(isset($obj->access_token)) echo 'access_token:'.$obj->access_token."<br>";
  17.     if(isset($obj->session_secret)) echo 'session_secret:'.$obj->session_secret."<br>";
  18.     if(isset($obj->session_key)) echo 'session_key:'.$obj->session_key."<br>";
  19.     if(isset($obj->scope)) echo 'scope:'.$obj->scope."<br>";
  20. }

(注:这里的“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

百度开发者中心:http://developer.baidu.com/console

发表评论 取消回复
表情 图片 链接 代码

  1. bingo
    bingo Lv 1

    我用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

    这是为什么?

    • mengkun
      mengkun 站长

      @bingo不清楚……很久没研究这个 Api 了

分享