dever 4 سال پیش
کامیت
0f73b26b15
5فایلهای تغییر یافته به همراه520 افزوده شده و 0 حذف شده
  1. 57 0
      config/wechat.php
  2. 96 0
      database/account.php
  3. 8 0
      index.php
  4. 346 0
      lib/Client.php
  5. 13 0
      src/Request.php

+ 57 - 0
config/wechat.php

@@ -0,0 +1,57 @@
+<?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/userinfo',
+	'param' => array
+	(
+		'access_token' => 'access_token',
+		'openid' => 'openid',
+		'lang' => 'zh_CN',
+	)
+);
+
+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})',
+		),
+	),
+);

+ 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');

+ 346 - 0
lib/Client.php

@@ -0,0 +1,346 @@
+<?php
+# Oauth Client
+namespace Oauth\Lib;
+
+use Dever;
+use Dever\Session\Oper as Save;
+use Passport\Lib\Base;
+
+class Client extends Base
+{
+	/**
+	 * @desc prefix
+	 * @var string
+	 */
+	private $prefix = 'v3_';
+
+	/**
+	 * @desc account
+	 * @var int
+	 */
+	private $account = 1;
+
+	/**
+	 * @desc save
+	 * @var object
+	 */
+	protected $session = null;
+
+	/**
+	 * @desc passport
+	 * @var object
+	 */
+	protected $passport = null;
+
+	/**
+	 * @desc request
+	 * @var array
+	 */
+	private $request = null;
+
+	/**
+	 * @desc config
+	 * @var array
+	 */
+	private $config = null;
+
+	public function __construct()
+	{
+		parent::__construct();
+		$this->initPassport();
+		$this->initSave();
+		$this->initRequest();
+		$this->initAccount();
+		$this->initSource();
+        $this->initSystem();
+		$this->initSourceType();
+		$this->initRefer();
+		$this->initConfig();
+	}
+
+	private function initPassport()
+	{
+		$this->passport = Dever::load('passport/lib/base');
+	}
+
+	private function initSave()
+	{
+		$this->session = 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->session->get($this->prefix . 'oauth_account');
+		$this->session->add($this->prefix . 'oauth_account', $this->account);
+	}
+
+	private function initSystem()
+	{
+		$this->system = (isset($this->request['system']) && $this->request['system']) ? $this->request['system'] : $this->session->get($this->prefix . 'oauth_system');
+		$this->session->add($this->prefix . 'oauth_system', $this->system);
+	}
+
+	private function initSourceType()
+	{
+		$this->source_type = (isset($this->request['source_type']) && $this->request['source_type']) ? $this->request['source_type'] : $this->session->get($this->prefix . 'oauth_source_type');
+		$this->session->add($this->prefix . 'oauth_source_type', $this->source_type);
+	}
+
+	private function initSource()
+	{
+		$this->source = (isset($this->request['source']) && $this->request['source']) ? $this->request['source'] : $this->session->get($this->prefix . 'oauth_source');
+		$this->session->add($this->prefix . 'oauth_source', $this->source);
+	}
+
+	private function initRefer()
+	{
+		$this->refer = (isset($this->request['refer']) && $this->request['refer']) ? $this->request['refer'] : $this->session->get($this->prefix . 'oauth_refer');
+		$this->session->add($this->prefix . '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()
+	{
+		$info = $this->info();
+		if ($info) {
+			if ($this->refer) {
+				$refer = urldecode($this->refer);
+				Dever::location($refer);
+			} else {
+				return true;
+			}
+		}
+		$id = Dever::id();
+		$this->session->add($this->prefix . '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 = '')
+	{
+		$this->js = true;
+		if ((isset($this->request['js']) && $this->request['js'])) {
+			$this->js = false;
+		}
+		if ($this->js == true && $url) {
+			return $this->output($url);
+		} else {
+			$id = $this->session->get($this->prefix . 'oauth_id');
+			if (isset($this->config['token']['param'])) {
+				if (!$this->session->get($this->prefix . '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);
+
+					if (isset($result['errmsg'])) {
+						Dever::alert($result['errmsg']);
+					}
+
+					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;
+				}
+			}
+			
+			if (isset($this->config['token']['response']) && $this->config['token']['response']) {
+				# 进入绑定流程吧
+				return $this->bind();
+			}
+		}
+		Dever::alert('登录失败');
+	}
+	
+	/**
+	 * @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'];
+
+		if (!$data) {
+			Dever::alert('错误的数据');
+		}
+		
+		$get = $this->request;
+		
+		$id = false;
+		
+		if (isset($get['id']) && $get['id'] > 0) {
+			$id = $get['id'];
+		}
+		
+		$user = $this->update($data, $id);
+		# 跳转吧,从哪来去哪吧
+		if ($this->refer) {
+			$refer = urldecode($this->refer);
+			Dever::location($refer);
+		} else {
+	        return $user;
+		}
+	}
+
+	/**
+	 * @desc 绑定数据
+	 */
+	private function update($data, $id)
+	{
+        $this->param('user', 'access_token', $data['access_token']);
+		$this->param('user', 'openid', $data['openid']);
+
+		$userinfo = Dever::json_decode(Dever::curl($this->config['user']['url'], $this->config['user']['param']));
+		if (!$userinfo) {
+			return;
+		}
+		
+        //$user['bind'] = 1;
+        $user['temp'] = 2;
+        //$user['username'] = Dever::emoji($userinfo['nickname']);
+        $user['username'] = $userinfo['nickname'];
+        if ($userinfo['headimgurl']) {
+            //$update['set_avatar'] = $this->sessionAvatar($pic);
+          	$user['avatar'] = $userinfo['headimgurl'];
+        }
+        
+        if ($userinfo['city']) {
+            $user['city'] = $userinfo['city'];
+        }
+
+        if ($userinfo['province']) {
+            $user['province'] = $userinfo['province'];
+        }
+
+        if ($userinfo['country']) {
+            $user['country'] = $userinfo['country'];
+        }
+
+    	$user = $this->passport->wechat($data, $user, $this->account, $this->system, $this->source_type, $this->source);
+
+        return $user;
+	}
+	
+	/**
+	 * @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;
+	}
+}