dever 5 years ago
commit
a79502d231
7 changed files with 623 additions and 0 deletions
  1. 58 0
      config/wechat.php
  2. 96 0
      database/account.php
  3. 92 0
      database/user.php
  4. 111 0
      database/wechat.php
  5. 8 0
      index.php
  6. 245 0
      lib/Client.php
  7. 13 0
      src/Request.php

+ 58 - 0
config/wechat.php

@@ -0,0 +1,58 @@
+<?php
+# wechat基本配置
+
+# 第一步 请求
+$config['auth'] = array
+(
+	'url' => 'https://open.weixin.qq.com/connect/oauth2/authorize',
+	'param' => array
+	(
+		'appid' => '',
+		'redirect_uri' => '',
+		# 重命名,如果key不是response_type的话
+		//'response_type' => array('response_type', 'code'),
+		'response_type' => 'code',
+		'scope' => 'snsapi_userinfo',
+		'state' => '',
+		//'contact' => '#wechat_redirect',
+	)
+);
+
+# 第二步 获取token
+$config['token'] = array
+(
+	'url' => 'https://api.weixin.qq.com/sns/oauth2/access_token',
+	'param' => array
+	(
+		'appid' => '',
+		'secret' => '',
+		'code' => '',
+		'grant_type' => 'authorization_code',
+	),
+	'response' => array
+	(
+		'access_token' => '',
+		'expires_in' => '',
+		'refresh_token' => '',
+		'openid' => '',
+		'unionid' => '',
+		'scope' => '',
+		'errcode' => '',
+		'errmsg' => '',
+	)
+);
+
+# 第三步 获取用户信息
+$config['user'] = array
+(
+	'url' => 'https://api.weixin.qq.com/sns/oauth2/access_token',
+	'param' => array
+	(
+		'appid' => 'appid',
+		'secret' => 'secret',
+		'code' => 'code',
+		'grant_type' => 'authorization_code',
+	)
+);
+
+return $config;

+ 96 - 0
database/account.php

@@ -0,0 +1,96 @@
+<?php
+
+$type = array
+(
+	'wechat' => '微信',
+);
+
+return array
+(
+	# 表名
+	'name' => 'account',
+	# 显示给用户看的名称
+	'lang' => '第三方管理',
+	'order' => 10,
+	# 数据结构
+	'struct' => array
+	(
+	
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			'search'	=> 'order',
+			'list'		=> true,
+		),
+
+		'name'		=> array
+		(
+			'type' 		=> 'varchar-60',
+			'name' 		=> '账户名称',
+			'default' 	=> '',
+			'desc' 		=> '账户名称',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'type'		=> array
+		(
+			'type' 		=> 'varchar-30',
+			'name' 		=> '账户类型',
+			'default' 	=> 'wechat',
+			'desc' 		=> '账户类型',
+			'match' 	=> 'is_string',
+			'update'	=> 'radio',
+			'option'	=> $type,
+			'search'	=> 'select',
+			'list'		=> true,
+		),
+
+		'appid'		=> array
+		(
+			'type' 		=> 'varchar-150',
+			'name' 		=> 'appid',
+			'default' 	=> '',
+			'desc' 		=> 'appid',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+		'appsecret'		=> array
+		(
+			'type' 		=> 'varchar-300',
+			'name' 		=> 'appsecret',
+			'default' 	=> '',
+			'desc' 		=> 'appsecret',
+			'match' 	=> 'is_string',
+			'update'	=> 'text',
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '申请时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'insert'	=> true,
+			'search'	=> 'date',
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+);

+ 92 - 0
database/user.php

@@ -0,0 +1,92 @@
+<?php
+
+return array
+(
+	# 表名
+	'name' => 'user',
+	# 显示给用户看的名称
+	'lang' => '用户绑定列表',
+	'order' => 10,
+	'menu' => false,
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			//'search'	=> 'order',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+		
+		'account_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属账户',
+			'default' 	=> '1',
+			'desc' 		=> '所属账户',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'select',
+			'list'		=> '{account_id} > 0 ? Dever::load("oauth/account-one#name", {account_id}) : "未知"',
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+		),
+
+		'unionid'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'unionid-第三方唯一id',
+			'default' 	=> '',
+			'desc' 		=> 'unionid',
+			'match' 	=> 'is_string',
+			//'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'search'	=> 'date',
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+	
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+		'delete' => false,
+	),
+	
+	# request 请求接口定义
+	'request' => array
+	(
+		
+	),
+);

+ 111 - 0
database/wechat.php

@@ -0,0 +1,111 @@
+<?php
+
+return array
+(
+	# 表名
+	'name' => 'wechat',
+	# 显示给用户看的名称
+	'lang' => '微信openid',
+	'order' => 10,
+	'menu' => false,
+	# 数据结构
+	'struct' => array
+	(
+		'id' 		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> 'ID',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+			//'search'	=> 'order',
+			'order'		=> 'desc',
+			'list'		=> true,
+		),
+		
+		'account_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '所属账户',
+			'default' 	=> '1',
+			'desc' 		=> '所属账户',
+			'match' 	=> 'is_numeric',
+			'update'	=> 'select',
+			'list'		=> '{account_id} > 0 ? Dever::load("oauth/account-one#name", {account_id}) : "未知"',
+		),
+
+		'uid'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+		),
+
+		'user_id'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '用户',
+			'default' 	=> '',
+			'desc' 		=> '',
+			'match' 	=> 'is_numeric',
+		),
+
+		'openid'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'openid-微信的唯一用户id',
+			'default' 	=> '',
+			'desc' 		=> 'openid',
+			'match' 	=> 'is_string',
+			//'update'	=> 'text',
+			'search'	=> 'fulltext',
+			'list'		=> true,
+		),
+
+		'session_key'		=> array
+		(
+			'type' 		=> 'varchar-50',
+			'name' 		=> 'session_key',
+			'default' 	=> '',
+			'desc' 		=> 'session_key',
+			'match' 	=> 'is_string',
+			//'update'	=> 'text',
+		),
+
+		'state'		=> array
+		(
+			'type' 		=> 'tinyint-1',
+			'name' 		=> '状态',
+			'default' 	=> '1',
+			'desc' 		=> '请选择状态',
+			'match' 	=> 'is_numeric',
+		),
+		
+		'cdate'		=> array
+		(
+			'type' 		=> 'int-11',
+			'name' 		=> '录入时间',
+			'match' 	=> array('is_numeric', time()),
+			'desc' 		=> '',
+			# 只有insert时才生效
+			'search'	=> 'date',
+			'insert'	=> true,
+			'list'		=> 'date("Y-m-d H:i:s", {cdate})',
+		),
+	),
+	
+	'manage' => array
+	(
+		'insert' => false,
+		'edit' => false,
+		'delete' => false,
+	),
+	
+	# request 请求接口定义
+	'request' => array
+	(
+		
+	),
+);

+ 8 - 0
index.php

@@ -0,0 +1,8 @@
+<?php
+
+define('DEVER_APP_NAME', 'oauth');
+define('DEVER_APP_LANG', '第三方登录');
+define('DEVER_APP_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+define('DEVER_MANAGE_ORDER', 1);
+define('DEVER_MANAGE_ICON', 'glyphicon glyphicon-filter layui-icon-group');
+include(DEVER_APP_PATH . '../boot.php');

+ 245 - 0
lib/Client.php

@@ -0,0 +1,245 @@
+<?php
+# Oauth Client
+namespace Oauth\Lib;
+
+use Dever;
+use Dever\Session\Oper as Save;
+
+class Client
+{
+	/**
+	 * @desc account
+	 * @var int
+	 */
+	private $account = 1;
+
+	/**
+	 * @desc save
+	 * @var object
+	 */
+	private $save = null;
+
+	/**
+	 * @desc request
+	 * @var array
+	 */
+	private $request = null;
+
+	/**
+	 * @desc config
+	 * @var array
+	 */
+	private $config = null;
+
+	public function __construct()
+	{
+		$this->initSave();
+		$this->initRequest();
+		$this->initAccount();
+		$this->initRefer();
+		$this->initConfig();
+	}
+
+	private function initSave()
+	{
+		$this->save = new Save(DEVER_PROJECT, 'session');
+	}
+
+	private function initRequest()
+	{
+		$this->request = Dever::input();
+	}
+
+	private function initAccount()
+	{
+		$this->account = (isset($this->request['account']) && $this->request['account']) ? $this->request['account'] : $this->save->get('oauth_account');
+		$this->save->add('oauth_account', $this->account);
+	}
+
+	private function initRefer()
+	{
+		$this->refer = (isset($this->request['refer']) && $this->request['refer']) ? $this->request['refer'] : $this->save->get('oauth_refer');
+		$this->save->add('oauth_refer', $this->refer);
+	}
+
+	private function initConfig()
+	{
+		$this->config = Dever::db('oauth/account')->one($this->account);
+		if (!$this->config) {
+			Dever::alert('账户错误');
+		}
+		$this->config += Dever::config($this->config['type'])->cAll;
+	}
+
+	/**
+	 * @desc oauth请求
+	 */
+	public function auth()
+	{
+		$id = Dever::id();
+		$this->save->add('oauth_id', $id);
+		$this->param('auth', 'appid', $this->config['appid']);
+		$this->param('auth', 'redirect_uri', Dever::url('request/callback?account=' . $this->account, 'oauth'));
+		$this->param('auth', 'state', $id);
+		$this->param('auth', 'response_type');
+		$this->param('auth', 'scope');
+		
+		print_r($this->config['auth']);die;
+
+		$url = $this->config['auth']['url'] . '?' . http_build_query($this->config['auth']['param']);
+
+		Dever::location($url);
+	}
+	
+	/**
+	 * @desc oauth请求 callback
+	 */
+	public function callback($url = '')
+	{
+		if ((isset($this->request['js']) && $this->request['js'])) {
+			$this->_js = false;
+		}
+		if ($this->_js == true && $url) {
+			return $this->output($url);
+		} else {
+			$id = $this->save->get('oauth_id');
+			if (isset($this->config['token']['param'])) {
+				if (!$this->save->get('oauth_refresh')) {
+					$this->param('token', 'code');
+					$this->param('token', 'appid', $this->config['appid']);
+					$this->param('token', 'secret', $this->config['appsecret']);
+					$this->param('token', 'grant_type');
+
+					$result = Dever::curl($this->config['token']['url'], $this->config['token']['param']);
+
+					$result = Dever::json_decode($result);
+
+					parse_str(http_build_query($result), $this->request);
+
+					$this->response('token', 'access_token');
+					$this->response('token', 'expires_in');
+					$this->response('token', 'refresh_token');
+					$this->response('token', 'openid');
+					$this->response('token', 'unionid');
+					$this->response('token', 'scope');
+					$this->response('token', 'errcode');
+					$this->response('token', 'errmsg');
+				} else {
+					# 由于refresh token是长期有效的,所以这里无需再次获取了。之后通过这个refresh获取access token就行了
+					return;
+				}
+			}
+			
+			# 进入绑定流程吧
+			$this->bind($data);
+		}
+	}
+	
+	/**
+	 * @desc 重新获取token
+	 * @author leo(suwi.bin)
+	 * @date 2012-08-27
+	 */
+	protected function refresh()
+	{
+		$data = $this->request();
+		$state = false;
+		if(isset($data['token_refresh']) && $data['token_refresh'])
+		{
+			$this->param('refresh', 'refresh_token',		 $data['token_refresh']);
+			$this->param('refresh', 'client_id',			 $this->_config['id']);
+			$this->param('refresh', 'client_secret',		 $this->_config['key']);
+			$return = json_decode($this->_curl('post', $this->param['refresh']), true);
+			if(isset($return['error']))
+			{
+				Dever::alert('参数错误');
+			}
+			if(isset($return['access_token']) && $return['access_token'])
+			{
+				$update['token_code'] = $return['access_token'];
+				$update['token_type'] = $return['token_type'];
+				$update['token_time'] = $return['expires_in'];
+				$state = $this->_update($update, $data['id']);
+			}
+		}
+		return $state;
+	}
+	
+	/**
+	 * @desc 绑定数据
+	 */
+	private function bind()
+	{
+		$data = $this->config['token']['response'];
+		
+		$get = $this->request();
+		
+		$id = false;
+		
+		if(isset($get['id']) && $get['id'] > 0)
+		{
+			$id = $get['id'];
+		}
+		
+		$this->_update($data, $id);
+		
+		# 跳转吧,从哪来去哪吧
+		if($this->refer)
+		{
+			$refer = base64_decode($this->refer);
+			Dever::location($refer);
+		}
+	}
+	
+	/**
+	 * @desc 输出js内容
+	 */
+	private function output($url)
+	{
+		$html = 
+		'<script>   
+			var params = {}, queryString = location.hash.substring(1),
+			regex = /([^&=]+)=([^&]*)/g, m;
+			while (m = regex.exec(queryString))
+			{
+				params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
+			}
+
+			location.href="'.$url.'&js=false&" + queryString;
+		</script>';
+		echo $html;die;
+	}
+	
+	/**
+	 * @desc 请求参数
+	 */
+	private function param($type, $key, $value = false)
+	{
+		$this->compatible($this->config[$type]['param'], $key, $value);
+	}
+
+	/**
+	 * @desc 响应参数
+	 */
+	private function response($type, $key, $value = false)
+	{
+		$this->compatible($this->config[$type]['response'], $key, $value);
+	}
+
+	/**
+	 * @desc 兼容处理
+	 */
+	private function compatible(&$param, $key, $value = false)
+	{
+		$default = false;
+		if (isset($param[$key]) && is_array($param[$key])) {
+			$nkey = $param[$key][0];
+			$default = $param[$key][1];
+			unset($param[$key]);
+			$key = $nkey;
+		} else {
+			$default = $param[$key];
+		}
+		return $param[$key] = ($value ? $value : (isset($this->request[$key]) ? $this->request[$key] : $default));
+	}
+}

+ 13 - 0
src/Request.php

@@ -0,0 +1,13 @@
+<?php
+namespace Oauth\Src;
+
+use Dever;
+use Oauth\Lib\Client;
+
+class Request extends Client
+{
+	public function test()
+	{
+		echo 11;die;
+	}
+}