记录一些对接 Coding 授权登录的代码分享!有需要的拿去!

本来已开始准备对接新浪微博的,因为我实际项目是部署在香港的服务器上的,好巧不巧的那台香港的服务器就是打死请求不到新浪微博的接口,改了host也不行(注意:改host后,ping/telnet 地区能通,但是实际上我用php的curl包括用系统自带的curl请求都直接断开链接了,直接放弃治疗了),代码托管平台现在基本都对接齐了,一个gitee(码云),一个github,今天又把coding对接了,这怕是能囊括90%的程序员代码托管平台的账号了!

这是个连续剧

因为前面我已经有博文记录了对接的具体流程,这里就不重复写一些废话了,主要说明几点,我改了一下 HttpRequest 工具类,因为现在有一个场景是 coding 的有些授权接口是 POST 请求,但是实际传参是 GET 的方式,旧的 HttpRequest 不支持,因此改动了下!其它其实就没啥了!

申请配图

Xnip2021-11-11_13-10-39.jpg

Xnip2021-11-11_13-11-14.jpg

直入正题

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];
            }
        }
    }
}