自己写的Oauth协议第三方登陆授权系统(单账户多站点登陆)

1468926217

相信大家都用过第三方登陆,第三方登陆的好处是不用注册,而且只需记住一个账号密码即可,可以那么问题来了。
什么是Oauth协议

OAuth(开放授权)是一个开放标准。

允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息。

而这种授权无需将用户提供用户名和密码提供给该第三方网站。

OAuth允许用户提供一个令牌给第三方网站,一个令牌对应一个特定的第三方网站,同时该令牌只能在特定的时间内访问特定的资源。
OAuth认证和授权的过程

1、用户访问第三方网站网站,想对用户存放在服务商的某些资源进行操作。

2、第三方网站向服务商请求一个临时令牌。

3、服务商验证第三方网站的身份后,授予一个临时令牌。

4、第三方网站获得临时令牌后,将用户导向至服务商的授权页面请求用户授权,然后这个过程中将临时令牌和第三方网站的返回地址发送给服务商。

5、用户在服务商的授权页面上输入自己的用户名和密码,授权第三方网站访问所相应的资源。

6、授权成功后,服务商将用户导向第三方网站的返回地址。

7、第三方网站根据临时令牌从服务商那里获取访问令牌。

8、服务商根据令牌和用户的授权情况授予第三方网站访问令牌。

9、第三方网站使用获取到的访问令牌访问存放在服务商的对应的用户资源。

老规矩的来张图简单粗暴的了解Oauth

我就是贪在他只需记住一个账号密码即可登陆其他的,比如我要登陆几个系统的后台,密码账号什么的一大堆,但是使用第三方登陆授权可以轻松解决这个问题,而且可以设置用户权限,于是我选择了使用第三方登陆授权解决多账号多站点登陆,实现一个账号登陆多个系统。
DEMO

账号1:Ape 密码:Ape

账号2:test 密码:test

三个demo:https://api.xiaocp.com/oauthdemo/

SDK开发工具包下载Ape_SDK1.0
SDK介绍

下载sdk解压后有4个php文件

config.php

<?php
/**

config是配置文件,分别给网站配上APPID,APPKEY,CALLBACK三个属性,三者都是一一对应的

接下来是Oauth.php核心类

<?php
/**

  • Created by PhpStorm.
  • User: Ape
  • Date: 2016-7-17
  • Time: 16:04
  • /
    require_once(‘config.php’);
    require_once(‘URL.class.php’);

class Oauth{

const VERSION = "1.0";
const GO_LOGIN_URL = "https://api.xiaocp.com/oauth/index/login";
const GET_OPENID_URL = "https://api.xiaocp.com/oauth/index/get_token";
const GET_USER_INFO_URL = "https://api.xiaocp.com/oauth/index/get_user_info";

public $urlUtils;
protected $error;

private static $data;

public function __construct(){
    session_start();
    $this->urlUtils = new URL();
    $this->error = new ErrorCase();
}

public function login(){
    $appid = APE_OAUTH_SDK_APPID;
    $appkey = APE_OAUTH_SDK_APPKRY;
    $callback = APE_OAUTH_SDK_CALLBACK;

    //-------生成唯一随机串防CSRF攻击
    $state = md5(uniqid(rand(), true));
    $_SESSION['state'] = $state;

    //-------构造请求参数列表
    $keysArr = array(
        "client_id" => $appid,
        "client_key" => $appkey,
        "redirect_uri" => $callback,
        "state" => $state,
    );

    $login_url =  $this->urlUtils->combineURL(self::GO_LOGIN_URL, $keysArr);
    header("Location:$login_url");
}

public function callback(){
    //--------验证state防止CSRF攻击
    $state = $_SESSION['state'];
    if($_GET['state'] != $state){
        $this->error->showError("30001");
    }

    //-------请求参数列表
    $keysArr = array(
        "client_id" => APE_OAUTH_SDK_APPID,
        "redirect_uri" => APE_OAUTH_SDK_CALLBACK,
        "client_key" => APE_OAUTH_SDK_APPKRY,
        "code" => $_GET['code']
    );

    //------构造请求access_token的url
    $token_url = $this->urlUtils->combineURL(self::GET_OPENID_URL, $keysArr);
    $response = $this->urlUtils->get_contents($token_url);
    $msg = json_decode($response, true);
    return $msg['data'];
}

public function get_user_info($access_token = '', $open_id = ''){
    //-------请求参数列表
    $keysArr = array(
        "access_token" => $access_token,
        "open_id" => $open_id,
    );

    //------构造请求access_token的url
    $token_url = $this->urlUtils->combineURL(self::GET_USER_INFO_URL, $keysArr);
    $response = $this->urlUtils->get_contents($token_url);
    $msg = json_decode($response, true);

    return $msg['data'];
}

}

前面几个声明的常量是请求服务端地址,先是要调用login()函数进行请求转发,会弹出这么的个页面

这就是第三方请求登陆的页面,然后登陆成功会到code跟state参数回传到毁掉地址,state用于检验数据的一致性,code参数的值我在服务端设定了60秒失效,那么就要在这时间内调用callback()函数获取access_token与open_id,同一个用户的不同web应用的openid是不一样的,然后再调用get_user_info函数就可以拿到用户的资料什么的啦哈哈。