Files
plugins/Sinauth/AuthorizeAction.php
chorblack e75f275ef4
Some checks failed
定时更新GitHub源插件 / 自动更新GitHub插件 (push) Has been cancelled
Initial commit
2026-03-07 11:19:25 +08:00

196 lines
7.0 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Sinauth Plugin
*
* @copyright Copyright (c) 2015 jimmy.chaw (http://x3d.cnblogs.com)
* @license GNU General Public License 2.0
*
*/
class Sinauth_AuthorizeAction extends Typecho_Widget implements Widget_Interface_Do
{
private $db;
private $config;
private static $pluginName = 'Sinauth';
private static $tableName = 'users_oauth';
public function __construct($request, $response, $params = NULL)
{
parent::__construct($request, $response, $params);
$this->config = Helper::options()->plugin(self::$pluginName);
$this->db = Typecho_Db::get();
}
public function action(){
//跳转
if (!class_exists('SaeTOAuthV2')) {
require_once 'saetv2.ex.class.php';
}
$saeto_client = new SaeTOAuthV2($this->config->client_id, $this->config->client_secret);
$authorize_url = $saeto_client->getAuthorizeURL($this->config->callback_url, 'code');
$this->response->redirect($authorize_url);
exit;
}
/**
* 授权回调地址
*/
public function callback(){
if(empty($_GET['code'])) {
throw new Typecho_Exception(_t('无效请求!'));
}
//跳转
if (!class_exists('SaeTOAuthV2')) {
require_once 'saetv2.ex.class.php';
}
$saeto_client = new SaeTOAuthV2($this->config->client_id, $this->config->client_secret);
//取access_token
$access_token = $saeto_client->getAccessToken('code', array('code' => trim($_GET['code']), 'redirect_uri' => $this->config->callback_url));
if (empty($access_token) || !is_array($access_token) || empty($access_token['uid'])) {
throw new Typecho_Exception(_t('获取access_token失败请返回重新授权'));
}
$table = $this->db->getPrefix() . self::$tableName;
$query = $this->db->query("SELECT * FROM {$table} WHERE openid='{$access_token['uid']}' AND plateform='sina'");
$users_oauth = $this->db->fetchRow($query);
if (!empty($users_oauth['uid'])) { //该新浪帐号已经绑定了用户
if (Typecho_Widget::widget('Widget_User')->hasLogin()) { /** 直接返回 */
$this->response->redirect(Typecho_Widget::widget('Widget_Options')->index);
} else { //让其直接登陆
$this->setUserLogin($users_oauth['uid']);
if (!Typecho_Widget::widget('Widget_User')->pass('contributor', true)) {
/** 不允许普通用户直接跳转后台 */
$this->response->redirect(Typecho_Widget::widget('Widget_Options')->profileUrl);
} else {
$this->response->redirect(Typecho_Widget::widget('Widget_Options')->adminUrl);
}
}
exit;
}
//该新浪帐号未绑定过
/** 如果已经登录 */
if (Typecho_Widget::widget('Widget_User')->hasLogin()) {
/** 直接绑定 */
$cookieUid = Typecho_Cookie::get('__typecho_uid');
$this->bindOauthUser($cookieUid, $access_token['uid'], 'sina', $access_token['expires_in']);
$this->response->redirect(Typecho_Widget::widget('Widget_Options')->index);
} else {
//取用户信息
$saetc_client = new SaeTClientV2($this->config->client_id, $this->config->client_secret, $access_token['access_token']);
$weibo_user = $saetc_client->show_user_by_id($access_token['uid']);
//创建用户
$uid = $this->registerFromWeiboUser($weibo_user);
if (!$uid) {
throw new Typecho_Exception(_t('创建帐号失败,请联系管理员!'));
}
$this->setUserLogin($uid);
$this->bindOauthUser($uid, $access_token['uid'], 'sina', $access_token['expires_in']);
$this->response->redirect(Typecho_Widget::widget('Widget_Options')->profileUrl);
}
//构造用户帐号
exit;
}
/**
* 根据微博用户信息创建帐号
*/
protected function registerFromWeiboUser(&$weibo_user) {
$hasher = new PasswordHash(8, true);
$generatedPassword = Typecho_Common::randString(7);
//TODO 用户名重复的问题
$uname = $weibo_user['name'];
$i = 0;
if (!Typecho_Widget::widget('Widget_Abstract_Users')->nameExists($uname)) { //用户名存在
echo 'here';
for ($i = 1; $i < 999; $i++) {
echo $i;
if (Typecho_Widget::widget('Widget_Abstract_Users')->nameExists($uname . '_' . $i)) {
$uname = $uname . '_' . $i;
break;
}
}
}
$dataStruct = array(
'name' => $uname,
'mail' => $weibo_user['idstr'] . ($i ? '_' . $i : '') . '@localhost.local',
'screenName'=> $weibo_user['screen_name'] . ($i ? '_' . $i : ''),
'password' => $hasher->HashPassword($generatedPassword),
'created' => time(),
'url' => $weibo_user['url'],
'group' => 'subscriber'
);
$insertId = Typecho_Widget::widget('Widget_Abstract_Users')->insert($dataStruct);
return $insertId;
}
public function nameExists($name)
{
$select = $this->db->select()
->from('table.users')
->where('name = ?', $name)
->limit(1);
$user = $this->db->fetchRow($select);
return $user ? false : true;
}
/**
* 设置用户登陆状态
*/
protected function setUserLogin($uid, $expire = 30243600) {
Typecho_Widget::widget('Widget_User')->simpleLogin($uid);
$authCode = function_exists('openssl_random_pseudo_bytes') ?
bin2hex(openssl_random_pseudo_bytes(16)) : sha1(Typecho_Common::randString(20));
Typecho_Cookie::set('__typecho_uid', $uid, time() + $expire);
Typecho_Cookie::set('__typecho_authCode', Typecho_Common::hash($authCode), time() + $expire);
//更新最后登录时间以及验证码
$this->db->query($this->db
->update('table.users')
->expression('logged', 'activated')
->rows(array('authCode' => $authCode))
->where('uid = ?', $uid));
}
public function bindOauthUser($uid, $openid, $plateform = 'sina', $expires_in = 0) {
$rows = array(
'openid' => $openid,
'uid' => $uid,
'plateform' => $plateform,
'bind_time' => time(),
'expires_in' => $expires_in
);
return $this->db->query($this->db->insert('table.users_oauth')->rows($rows));
}
}