在过去的几年中,我运行了我自己的版本管理(SVN)服务器,在免费空间运行过,最近也在付费服务器上运行过。这主要是因为过去我的工作是私密性的,而我又对SVN很熟悉,还发现了TortoiseSVN 客户端很棒并且便于使用。经过这些年,我的需求已经改变并进一步提升,特别是在自从我开始制作这些教程以来的近几个月当中。因此,我决定开始把我的新项目和我的一些教程转移到GitHub。
在过去的几年中,我已经观察了GitHub的发展过程,而它已经有点形成气候了。根据他们最近融资的1亿欧元来看,这是个难以想想的数字,并且表明他们真的有一些大计划。针对我而言,我将会利用免费仓库来存放我的教程源代码。这样一来,我希望能以与用户群体更好的互动作为窗口,来了解人们到底用我代码示例做了什么。
这是我的OAuth2教程的最后一篇,因此如果你刚刚开始看我的文章,这篇文章将会借鉴我之前的那些OAuth 2.0 教程. 每个站点(Twitter, LinkedIn和现在的GitHub)都实现了他们自己的OAuth2认证流程,而实现稍有不同,使用了不同的方法或者不同类型的OAuth。你现在应该可以访问几乎任何你遇到的OAuth2实现。如果在这个过程中你发现了任何困难,请自由评论或者发E-mail给我。
这次我们将要创建一个简单的插件,它提供了你的基本信息,并列举你的仓库和每个仓库中有多少分支和看管员。把它想象成一个GitHub的事务卡;实际上,如果你把它与我之前的LinkedIn教程相结合,你将会有一个相当全面的方法来展示你的简历和工作经历。
要通过GitHub认证,你将需要在这里注册你的应用。如果你还没有账户,你可以在这里免费注册。回传的URL链接是跳转到我们的github.php文件的链接,它应该这样:
http://yoursite.com/wordpress/wp-admin/options-general.php?page=github.php
首先我们需要创建我们的OAuth实例类。它的模式类似于我们之前的OAuth2教程中惯用的模式,因此,我们可以快速的跳过起始阶段。这个实例定义了我们将要使用的所有方法,后面我会逐个详细讲解。
<?php class GitHub_Example { public function __construct() { } public function add_github_admin_menu() { } public function add_github_admin_page() { } public function render_shortcode($atts) { } public function enqueue_github_style() { } } $github = new GitHub_Example(); ?>
GitHub_Example类在本教程中可能有两个用途。首先,是为WordPress建立和配置插件;其次,是在认证认知之后,当我们从github.com跳转回来时,让我们可以对OAuth代码进行解析。
现在,我们只建立插件。因此,我们需要使用add_shortcode注册我们的简码,添加我们的菜单函数并使用add_action来让我们的CSS列队等候。
public function __construct() { add_shortcode('github', array($this, 'render_shortcode')); add_action('admin_menu', array($this, 'add_github_admin_menu')); add_action('wp_footer', array($this, 'enqueue_github_style')); }
为了添加菜单,我们使用add_options_page,同时我们在这里把我们的CSS函数列队,以便在管理页面中使用。
public function add_github_admin_menu() { add_options_page('GitHub Options', 'GitHub', 'manage_options', 'github.php', array($this, 'add_github_admin_page')); add_action( 'admin_print_scripts', array($this, 'enqueue_github_style')); }
为了通过GitHub进行认证,我们需要存储客户端ID和我们之前建立的密钥。
因此我们将沿用我们的通常的做法,即回传给它自己和我们的条件认证按钮。在GitHub上认证的URL是“https://github.com/login/oauth/authorize?client_id=$api_key&scope=&state=$state&redirect_uri=$redirect”。状态还是一个base64编码的时间。这同时也是GitHub的OAuth实现开始变得不同的地方。这里我们不需要识别令牌类型,它总是默认设置成bearer令牌.
public function add_github_admin_page() { if ( !current_user_can( 'manage_options' ) ) { wp_die( __( 'You do not have sufficient permissions to access this page.' ) ); } if ( $_SERVER["REQUEST_METHOD"] == "POST" ){ update_option( 'GITHUB_API_KEY', $_POST['api_key'] ); update_option( 'GITHUB_API_SECRET_KEY', $_POST['api_secret_key'] ); } ?> <div class="github-admin-options"> <h1>GitHub Options</h1> <form name="options" method="POST" action="<?php echo $_SERVER['REQUEST_URI']; ?>"> <label for="api_key">API Key<span class="required">(*)</span>: </label> <input type="text" name="api_key" value="<?php echo get_option( 'GITHUB_API_KEY', '' ); ?>" size="70"> <br /> <label for="api_secret_key">Consumer Secret<span class="required">(*)</span>: </label> <input type="text" name="api_secret_key" value="<?php echo get_option( 'GITHUB_API_SECRET_KEY', '' ); ?>" size="70"> <br /> <label for="bearer_token">Authentication Token: </label> <input type="text" disabled value="<?php echo get_option( 'GITHUB_AUTHENTICATION_TOKEN', '' ); ?>" size="70"> <br /> <input class="button-primary" type="submit" name="save" /> <?php $state = base64_encode(time()); $redirect = get_template_directory_uri() . '/github.php'; $api_key = get_option( 'GITHUB_API_KEY' ); $api_secret = get_option( 'GITHUB_API_SECRET_KEY' ); $token = get_option( 'GITHUB_AUTHENTICATION_TOKEN' ); if($api_key && $api_secret && !$token) { $api_url = "https://github.com/login/oauth/authorize?client_id=$api_key&scope=&state=$state&∓redirect_uri=$redirect"; ?> <a class="button-primary" type="button" href="<?php echo $api_url; ?>">Authenticate</a> <?php } ?> <br/> <small>You can sign up for a API key <a href="https://developer.github.com/" target="_blank">here</a></small> </form> <br /> <?php echo do_shortcode('[github]'); ?> </div> <?php }
现在我们可以保存我们的客户端id和密钥了,我们必须完成认证步骤。
现在我们可以完成我们的构造器,并完善我们的认证。第一步是检查$_SERVER中的REQUEST_METHOD是否设置成GET,之后确认代码参数已经传出,并能在$_GET变量中使用。如果他们就绪,我们可以知道我们没有在WordPress之中运行,并且我们可以导入或者请求文件,之后在认证中使用。
这里又遇到了另一个与其他我们已经见过的OAuth实现不同的地方。你可以为access_token响应设置响应类型。我们使用wp_remote_post中的头参数值来实现。我们所要做的只是初始化队列,并把Accept值设置成‘application/json’。我们可以向access_token地址:‘https://github.com/login/oauth/access_token’发起一个POST请求。一旦我们得到响应,我们就解析并更新我们的配置,之后退出。
public function __construct() { if ( $_SERVER["REQUEST_METHOD"] == "GET" && isset($_GET['code'])){ require_once('../../../wp-config.php'); require_once(ABSPATH . 'wp-includes/plugin.php'); require_once(ABSPATH . 'wp-includes/pluggable.php'); require_once(ABSPATH . 'wp-includes/general-template.php'); $redirect = get_template_directory_uri() . '/github.php'; $api_key = get_option( 'GITHUB_API_KEY' ); $api_secret = get_option( 'GITHUB_API_SECRET_KEY' ); $args = array( 'method' => 'POST', 'httpversion' => '1.1', 'blocking' => true, 'headers' => array( 'Accept' => 'application/json' ), 'body' => array( 'code' => $_GET['code'], 'redirect_uri' => $redirect, 'client_id' => $api_key, 'client_secret' => $api_secret ) ); add_filter('https_ssl_verify', '__return_false'); $response = wp_remote_post( 'https://github.com/login/oauth/access_token', $args ); $keys = json_decode($response['body']); if($keys) { update_option( 'GITHUB_AUTHENTICATION_TOKEN', $keys->{'access_token'} ); } wp_redirect( get_bloginfo( 'url' ) . '/wp-admin/options-general.php?page=github.php' ); exit; } add_shortcode('github', array($this, 'render_shortcode')); add_action('admin_menu', array($this, 'add_github_admin_menu')); add_action('wp_footer', array($this, 'enqueue_github_style')); }
为了获得所有的信息,我们需要我们的简码,我们必须分别向API发起两个请求。第一个是获得基本的用户信息(https://api.github.com/user),第二个是获得仓库的列表(https://api.github.com/user/repos)。像所有现代的API一样,返回的内容是JSON格式的,因此很容易解析出我们需要的信息。首先,是我们的用户信息。这里,我们将会抓取用户名、URL和个人简历,以及他们的公共仓库、关注者的数量,和他们所关注的人的数量。
add_filter('https_ssl_verify', '__return_false'); $api_url = "https://api.github.com/user?access_token=$token"; $response = wp_remote_get( $api_url ); $json = json_decode( $response['body'] ); $return .= '<div class="github">'; $return .= '<h2><a href="' . $json->{'html_url'} . '" target="_blank">' . $json->{'name'} . '</a></h2>'; $return .= '<div class="bio">'; $return .= '<span>' . $json->{'bio'} . '</span>'; $return .= '</div>'; $return .= '<div class="counts">'; $return .= '<div>' . $json->{'public_repos'} . '<br/><span>repos</span></div>'; $return .= '<div>' . $json->{'followers'} . '<br/><span>followers</span></div>'; $return .= '<div>' . $json->{'following'} . '<br/><span>following</span></div>'; $return .= '</div>';
Next up it’s the list of repositories and how many forks have been made and how many people are watching them. Each repository is returned, so we just need to loop through them and grab the values we are interested in.
$api_url = "https://api.github.com/user/repos?access_token=$token"; $response = wp_remote_get( $api_url ); $json = json_decode( $response['body'] ); $return .= '<ol class="repos">'; foreach($json as $i => $repos) { $return .= '<li>'; $return .= '<h3><a href="' . $repos->{'html_url'} . '" target="_blank" title="' . $repos->{'description'} . '">' . str_replace('_', ' ', $repos->{'name'} ) . '</a></h3>'; $return .= '<div>'; $return .= '<div>'; $return .= $repos->{'forks_count'}; $return .= '<br/><span>forks</span>'; $return .= '</div>'; $return .= '<div>'; $return .= $repos->{'watchers_count'}; $return .= '<br/><span>watchers</span>'; $return .= '</div>'; $return .= '</div>'; $return .= '</li>'; } $return .= '</ol>'; $return .= '</div>';
You can see the full render_shortcode function in the source download
我已经在之前的HTML中导入了一些基本的CSS类,并且我已经为你提供了一个布局样例来试用。完整的CSS如下。它所做的只是将用户的详细信息居中,并且用行内元素展示仓库。这样,它能够适应更小的屏幕。
div.github h2{ text-align: center; } div.github div.counts { text-transform: uppercase; text-align: center; } div.github div.counts div { display: inline-block; padding: 5px; } div.github ol.repos { list-style: none; margin: 0px; padding: 0px; } div.github ol.repos li{ width: 120px; height: 120px; text-align: center; font-size: 12px; border: 1px dashed #000000; -webkit-border-radius: 20px; -moz-border-radius: 20px; border-radius: 20px; background-color: #e1e1e1; position: relative; display: inline-table; margin: 5px; } div.github ol.repos li h3{ padding: 0px; margin: 5px 0px; } div.github ol.repos li a, div.github ol.repos li a:hover, div.github ol.repos li a:visited { text-align: center; text-decoration: none; } div.github ol.repos li > div{ border-top: 1px dashed #000000; position: absolute; bottom: 5px; width: 100%; } div.github ol.repos li div div{ display: inline-block; font-size: 25px; width: 50%; margin-top: 8px; } div.github ol.repos li div div span{ font-size: 8px; text-transform: uppercase; }请在我的任意仓库中关注/扩展/评论,很希望能看到你用他们做了什么。
评论删除后,数据将无法恢复
评论(0)