记录一些对接 Coding 授权登录的代码分享!有需要的拿去!
本来已开始准备对接新浪微博的,因为我实际项目是部署在香港的服务器上的,好巧不巧的那台香港的服务器就是打死请求不到新浪微博的接口,改了host也不行(注意:改host后,ping/telnet 地区能通,但是实际上我用php的curl包括用系统自带的curl请求都直接断开链接了,直接放弃治疗了),代码托管平台现在基本都对接齐了,一个gitee(码云),一个github,今天又把coding对接了,这怕是能囊括90%的程序员代码托管平台的账号了!
这是个连续剧
因为前面我已经有博文记录了对接的具体流程,这里就不重复写一些废话了,主要说明几点,我改了一下 HttpRequest
工具类,因为现在有一个场景是 coding 的有些授权接口是 POST 请求,但是实际传参是 GET 的方式,旧的 HttpRequest
不支持,因此改动了下!其它其实就没啥了!
- 第一集:记一次对接Gitee码云第三方授权登陆的经验分享!
- 第二集:记录一次对接Github授权登陆遇到的问题及经验分享!
- 第三集:就是本博文!
申请配图
直入正题
新 HttpRequest
工具类分享
<?php
namespace app\common\util;
/**
* 发送网络请求工具类
* @author huangjunjie
* @version 1.0.2
*/
class HttpRequest
{
/**
* 发送 post 请求
* @param $url
* @param array $data
* @param array $query
* @param array $header
* @param bool $json
* @return mixed
*/
public function post($url, $data = array(), $query = array(), $header = array(), $json = false)
{
// 初始化
$curl = curl_init();
// 设置选项,包括URL
$query = http_build_query($query);
// 拼接url
$url = $url . '?' . $query;
// 设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
// 设置请求头
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
// 设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
// 设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
// 设置post数据
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
// 关闭证书校验
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
// 执行命令
$output = curl_exec($curl);
// 关闭URL请求
curl_close($curl);
return $json ? json_decode($output, true) : $output;
}
/**
* 发送 GET 请求
* @param $url
* @param array $data
* @param array $header
* @param bool $json
* @return mixed
*/
public function get($url, $data = array(), $header = array(), $json = false)
{
// 初始化
$curl = curl_init();
// 设置选项,包括URL
$query = http_build_query($data);
// 拼接url
$url = $url . '?' . $query;
// 设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
// 设置头文件的信息作为数据流输出
curl_setopt($curl, CURLOPT_HEADER, 0);
// 设置请求头
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
// 设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 关闭证书校验
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
// 执行并获取HTML文档内容
$output = curl_exec($curl);
// 释放curl句柄
curl_close($curl);
return $json ? json_decode($output, true) : $output;
}
/**
* 发送 POST 请求,且确认返回值为json
* @param $url
* @param array $data
* @param array $query
* @param array $header
* @return mixed
*/
public function postJson($url, $data = array(), $query = array(), $header = array())
{
return $this->post($url, $data, $query, $header, true);
}
/**
* 发送 GET 请求,且确认返回值为json
* @param $url
* @param array $data
* @param array $header
* @return mixed
*/
public function getJson($url, $data = array(), $header = array())
{
return $this->get($url, $data, $header, true);
}
}
新 common.php 配置文件分享
<?php
// 码云授权登陆配置,相关页面:https://gitee.com/oauth/applications
const AUTH_LOGIN_GITEE_CLIENT_ID = ""; // 填你自己的 ClientID
const AUTH_LOGIN_GITEE_CLIENT_SECRET = ""; // 填你自己的 ClientSecret
const AUTH_LOGIN_GITEE_REDIRECT_URI = ""; // 填你自己的 回调地址
const AUTH_LOGIN_GITEE_GET_TOKEN = "https://gitee.com/oauth/token";
const AUTH_LOGIN_GITEE_GET_USERINFO = "https://gitee.com/api/v5/user";
const AUTH_LOGIN_GITEE_AUTH_URI = "https://gitee.com/oauth/authorize";
// Github授权登陆配置,相关页面:https://github.com/settings/developers
const AUTH_LOGIN_GITHUB_CLIENT_ID = ""; // 填你自己的 ClientID
const AUTH_LOGIN_GITHUB_CLIENT_SECRET = ""; // 填你自己的 ClientSecret
const AUTH_LOGIN_GITHUB_REDIRECT_URI = ""; // 填你自己的 回调地址
const AUTH_LOGIN_GITHUB_GET_TOKEN = "https://github.com/login/oauth/access_token";
const AUTH_LOGIN_GITHUB_GET_USERINFO = "https://api.github.com/user";
const AUTH_LOGIN_GITHUB_AUTH_URI = "https://github.com/login/oauth/authorize";
// Coding 授权登陆配置,相关页面:https://help.coding.net/openapi
const AUTH_LOGIN_CODING_CLIENT_ID = ""; // 填你自己的 ClientID
const AUTH_LOGIN_CODING_CLIENT_SECRET = ""; // 填你自己的 ClientSecret
const AUTH_LOGIN_CODING_REDIRECT_URI = ""; // 填你自己的 回调地址
const AUTH_LOGIN_CODING_TEAM_PREFIX = ""; // Coding专用,你团队的前缀
const AUTH_LOGIN_CODING_TEAM_DOMAIN = "https://" . AUTH_LOGIN_CODING_TEAM_PREFIX . ".coding.net";
const AUTH_LOGIN_CODING_GET_TOKEN = AUTH_LOGIN_CODING_TEAM_DOMAIN . "/api/oauth/access_token";
const AUTH_LOGIN_CODING_GET_USERINFO = AUTH_LOGIN_CODING_TEAM_DOMAIN . "/api/me";
const AUTH_LOGIN_CODING_AUTH_URI = AUTH_LOGIN_CODING_TEAM_DOMAIN . "/oauth_authorize.html";
新 Controller 分享
<?php
namespace app\oauth\controller;
use app\common\util\HttpRequest;
use think\facade\Request;
use think\response\Redirect;
/**
* 这个控制器修改了下,不继承 Controller了,方便你们复制直接用
* @author huangjunjie
* @version 1.0.0
*/
class Platform
{
/**
* 码云授权登陆,也负责承担回调页面的责任
* @return array|Redirect
*/
public function gitee()
{
// 通过回调函数获取code
$code = Request::get("code");
// 如果没有code则自动重定向到授权页面
if (is_null($code)) {
$url = AUTH_LOGIN_GITEE_AUTH_URI;
$query = http_build_query([
"client_id" => AUTH_LOGIN_GITEE_CLIENT_ID,
"redirect_uri" => AUTH_LOGIN_GITEE_REDIRECT_URI,
"response_type" => "code"
]);
return redirect($url . "?" . $query);
} else {
// 获取access_token
$request = new HttpRequest();
$login = $request->postJson(AUTH_LOGIN_GITEE_GET_TOKEN, [
"grant_type" => "authorization_code",
"code" => $code,
"client_id" => AUTH_LOGIN_GITEE_CLIENT_ID,
"redirect_uri" => AUTH_LOGIN_GITEE_REDIRECT_URI,
"client_secret" => AUTH_LOGIN_GITEE_CLIENT_SECRET,
]);
// 如果报错提示,没报错则请求获取用户信息接口
if (isset($login["error"])) {
return ["code" => 401, "msg" => $login["error_description"]];
} else {
// Gitee 这里是直接通过 GET 参数传递 Token
$userinfo = $request->getJson(AUTH_LOGIN_GITEE_GET_USERINFO, ["access_token" => $login["access_token"]]);
// 这里返回获得的用户信息,具体可自己根据实际业务继续走
return ["code" => 200, "data" => $userinfo];
}
}
}
/**
* Github授权登陆,也负责承担回调页面的责任
* @return array|Redirect
*/
public function github()
{
// 通过回调函数获取code
$code = Request::get("code");
// 如果没有code则自动重定向到授权页面
if (is_null($code)) {
$url = AUTH_LOGIN_GITHUB_AUTH_URI;
$query = http_build_query([
"client_id" => AUTH_LOGIN_GITHUB_CLIENT_ID,
"redirect_uri" => AUTH_LOGIN_GITHUB_REDIRECT_URI
]);
return redirect($url . "?" . $query);
} else {
// 获取access_token
$request = new HttpRequest();
$login = $request->post(AUTH_LOGIN_GITHUB_GET_TOKEN, [
"code" => $code,
"client_id" => AUTH_LOGIN_GITHUB_CLIENT_ID,
"redirect_uri" => AUTH_LOGIN_GITHUB_REDIRECT_URI,
"client_secret" => AUTH_LOGIN_GITHUB_CLIENT_SECRET,
]);
// 这是里Github需要注意的,Github默认返回不是json,而是一个普通的query字符串
// 因此这里我们使用PHP内置的 parse_str 将 query 字符串专为 json 数据
parse_str($login, $json);
// 如果报错提示,没报错则请求获取用户信息接口
if (isset($json["error"])) {
return ["code" => 401, "msg" => $json["error_description"]];
} else {
// 注意!这里Github需要在常规鉴权 Authorization 字段的基础上
// 还需要额外包含一个 User-Agent 字段,这里为了方便,就直接把默认的头部对应字段转发过去了
// 按照 Github 官方要求, 这里的 User-Agent 字段应该是联系方式或者应用地址
// Github 官方的意思就是:如果你敢捣乱,就方便我找到你!嗯!
$userinfo = $request->getJson(AUTH_LOGIN_GITHUB_GET_USERINFO, [], [
"Authorization: Bearer " . $json["access_token"],
"User-Agent: " . Request::header("user-agent")
]);
// 这里返回获得的用户信息,具体可自己根据实际业务继续走
return ["code" => 200, "data" => $userinfo];
}
}
}
/**
* coding授权登陆,也负责承担回调页面的责任
* @return array|Redirect
*/
public function coding()
{
// 通过回调函数获取code
$code = Request::get("code");
// 如果没有code则自动重定向到授权页面
if (is_null($code)) {
$url = AUTH_LOGIN_CODING_AUTH_URI;
$query = http_build_query([
"client_id" => AUTH_LOGIN_CODING_CLIENT_ID,
"redirect_uri" => AUTH_LOGIN_CODING_REDIRECT_URI,
"response_type" => "code",
"scope" => "user"
]);
return redirect($url . "?" . $query);
} else {
// 获取access_token
$request = new HttpRequest();
$login = $request->postJson(AUTH_LOGIN_CODING_GET_TOKEN, [], [
"client_id" => AUTH_LOGIN_CODING_CLIENT_ID,
"client_secret" => AUTH_LOGIN_CODING_CLIENT_SECRET,
"code" => $code,
"grant_type" => "authorization_code",
]);
// 如果报错提示,没报错则请求获取用户信息接口
if (isset($login["error"])) {
return ["code" => 401, "msg" => $login["error"]];
} else {
// Coding 这里是直接通过 GET 参数传递 Token
$userinfo = $request->getJson(AUTH_LOGIN_CODING_GET_USERINFO, ["access_token" => $login["access_token"]]);
// 这里返回获得的用户信息,具体可自己根据实际业务继续走
return ["code" => 200, "data" => $userinfo];
}
}
}
}