三方登录之微博登录

2018-02-26 11:07:20 查看 1351 回复 0

微博作为现在传播讯息的快捷途径之一,网站很有必要接入一下它的快捷登录!

既然如此,那就记录一个微博登录的代码吧!

逻辑是:1.根据微博开放平台接口得到微博帐号的openid。2.比对数据库判断用户。3.进行用户登录或者用户绑定。

控制器:auth

   function weibologin(){
    	$wblogin = new WeiboLogin();
    	$code = I('get.code','');
    	if(empty($code)){
    		$wblogin->getCode();
    	}
	
    	//var_dump(I('get.'));
    	$token = $wblogin->getToken($code);
    	//var_dump($token);
    	if(!$token){
    		$this->err('微博资料获取失败');
    	}
    	if(!$token['access_token'] || !$token['uid']){
    		$this->err('微博资料获取失败');
    	}
    	
    	$user = new userModel();
    	$res = $user->WeiboAutoLogin($token['access_token']);
    	if($res === false){
    		$this->err($user->getError());
    	}else if($res === true){
    		redirect(TRUE_DIR);
    	}else{
    		$wbinfo =  $wblogin->getWBInfo($token);
    		//var_dump($wbinfo);
    		if(isset($wbinfo['error'])){
    			$this->err($wbinfo['error']);
    		}
     		session('authinfo',$wbinfo);
     		session('authtype','weibo');
     		session('authopenid',$token['access_token']);
     		$this->redirect('index/bind');
    	}
    	
    	
    }

模型:user

//微博自动登录
    function WeiboAutoLogin($openid){
    	$user = $this->table('auth_user')->where(array('openid'=>$openid))->find();
    	if($user){
    		$res = $this->table('user')->where(array('id'=>$user['create_by']))->find();
    		if(!$res){
    			$this->error = '用户异常,无法登录';
    			return false;
    		}
    		if($res['status']==0){
    			$this->error = '帐号无法登录,请联系管理员';
    			return false;
    		}
    		self::login($res);
    		return true;
    	}else{
    		return U('index/bind');
    	}
    }

功能类:Weibologin

/**
	 * construct WeiboOAuth object
	 */
	function __construct($access_token = NULL, $refresh_token = NULL) {
		if(!C('WEIBO_LOGIN')){
			dir('请配置微博登陆参数');
		}
		$this->conf = C('WEIBO_LOGIN');
		$this->client_id = $this->conf['WB_AKEY'];
		$this->client_secret =  $this->conf['WB_SKEY'];
		$this->access_token = $access_token;
		$this->refresh_token = $refresh_token;
	}

	/**
	 * authorize接口
	 *
	 * 对应API:{@link http://open.weibo.com/wiki/Oauth2/authorize Oauth2/authorize}
	 *
	 * @param string $url 授权后的回调地址,站外应用需与回调地址一致,站内应用需要填写canvas page的地址
	 * @param string $response_type 支持的值包括 code 和token 默认值为code
	 * @param string $state 用于保持请求和回调的状态。在回调时,会在Query Parameter中回传该参数
	 * @param string $display 授权页面类型 可选范围: 
	 *  - default		默认授权页面		
	 *  - mobile		支持html5的手机		
	 *  - popup			弹窗授权页		
	 *  - wap1.2		wap1.2页面		
	 *  - wap2.0		wap2.0页面		
	 *  - js			js-sdk 专用 授权页面是弹窗,返回结果为js-sdk回掉函数		
	 *  - apponweibo	站内应用专用,站内应用不传display参数,并且response_type为token时,默认使用改display.授权后不会返回access_token,只是输出js刷新站内应用父框架
	 * @return array
	 */
	function getAuthorizeURL($response_type = 'code', $state = NULL, $display = NULL ) {
		$params = array();
		$params['client_id'] = $this->client_id;
		$params['redirect_uri'] = $this->conf['WB_CALLBACK_URL'];
		$params['response_type'] = $response_type;
		$params['state'] = $state;
		$params['display'] = $display;
		return $this->authorizeURL() . "?" . http_build_query($params);
	}
	
	//获取code
	function getCode(){
	
		//state参数用于防止CSRF攻击,成功授权后回调时会原样带回
// 		$state = md5(uniqid(rand(), TRUE));
// 		session('state',$state);
		//拼接URL
// 		$dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="
// 				. $this->app_id . "&redirect_uri=" . $this->my_url. "&state="
// 						.$state;
		$dialog_url = $this->getAuthorizeURL();
		exit("<script> top.location.href='" . $dialog_url . "'</script>");
	}
	//获取Token
	function getToken($code){
		$token=null;
		$keys = array();
		$keys['code'] = $code;
		$keys['redirect_uri'] = $this->conf['WB_CALLBACK_URL'];
		try {
			$token = $this->getAccessToken( 'code', $keys ) ;
		} catch (OAuthException $e) {
		}
		return $token;
	}
	//获取用户资料
	function getWBInfo($token){
		$params['access_token']=$token['access_token'];
		$params['uid']=$token['uid'];
		return $this->get('https://api.weibo.com/2/users/show.json',$params);
	}
	
	/**
	 * access_token接口
	 *
	 * 对应API:{@link http://open.weibo.com/wiki/OAuth2/access_token OAuth2/access_token}
	 *
	 * @param string $type 请求的类型,可以为:code, password, token
	 * @param array $keys 其他参数:
	 *  - 当$type为code时: array('code'=>..., 'redirect_uri'=>...)
	 *  - 当$type为password时: array('username'=>..., 'password'=>...)
	 *  - 当$type为token时: array('refresh_token'=>...)
	 * @return array
	 */
	function getAccessToken( $type = 'code', $keys ) {
		$params = array();
		$params['client_id'] = $this->client_id;
		$params['client_secret'] = $this->client_secret;
		if ( $type === 'token' ) {
			$params['grant_type'] = 'refresh_token';
			$params['refresh_token'] = $keys['refresh_token'];
		} elseif ( $type === 'code' ) {
			$params['grant_type'] = 'authorization_code';
			$params['code'] = $keys['code'];
			$params['redirect_uri'] = $keys['redirect_uri'];
		} elseif ( $type === 'password' ) {
			$params['grant_type'] = 'password';
			$params['username'] = $keys['username'];
			$params['password'] = $keys['password'];
		} else {
			throw new OAuthException("wrong auth type");
		}

		$response = $this->oAuthRequest($this->accessTokenURL(), 'POST', $params);
		$token = json_decode($response, true);
		if ( is_array($token) && !isset($token['error']) ) {
			$this->access_token = $token['access_token'];
			//$this->refresh_token = $token['refresh_token'];
		} else {
			throw new OAuthException("get access token failed." . $token['error']);
		}
		return $token;
	}

*weibologin 基于微博登录官方DEMO