宝塔LInux面板API

引言:

通过宝塔API,可以完全控制宝塔Linux面板的所有功能,包括第三方插件应用功能,事实上,在用户登录面板 后使用的所有功能也是通过相同的接口对接的,这意味着,如果你熟悉使用浏览器调试器,就可以轻松对照宝塔Linux 面板的操作参数完成一个第三方的前端对接。

签名算法

 api_sk = 接口密钥 (在面板设置页面-API接口中获取)
 request_time = 当前请求时间的uinx时间戳 (php:time() / python:time.time())
 request_token = md5(string(request_time) + md5(api_sk))
 PHP 示例: $request_token=md5($request_time . ‘’ . md5($api_sk))

注意事项:

  1. 请统一使用POST方式请求API接口

  2. 为了确保请求效率,请保存cookie,并在每次请求时附上cookie

  3. 为了面板安全考虑,请务必添加IP白名单

  4. 所有响应内容统一为Json数据格式

DEMO:

BtApiHttp.java:
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

public class BtApiHttp {
    private String BT_KEY ; // 接口密钥
    private String BT_PANEL ; // 面板地址

    // 如果希望多台面板,可以在实例化对象时,将面板地址与密钥传入
    public BtApiHttp(String btPanel, String btKey) {
        if (btPanel != null) BT_PANEL = btPanel;
        if (btKey != null) BT_KEY = btKey;
    }

    // 示例取面板日志
    public String getLogs() {
        // 拼接URL地址
        String url = BT_PANEL + "/data?action=getData";

        // 准备POST数据
        Map<String, String> pData = getKeyData(); // 取签名
        pData.put("table", "logs");
        pData.put("limit", "10");
        pData.put("tojs", "test");

        // 请求面板接口
        return httpPost(url, pData);
    }

    // 构造带有签名的关联数组
    private Map<String, String> getKeyData() {
        long nowTime = System.currentTimeMillis() / 1000;
        String requestToken = getMD5Hash(nowTime + getMD5Hash(BT_KEY));
        Map<String, String> pData = new HashMap<>();
        pData.put("request_token", requestToken);
        pData.put("request_time", String.valueOf(nowTime));
        return pData;
    }

    // 发起HTTP POST请求
    private String httpPost(String url, Map<String, String> data) {
        try {
            StringJoiner postData = new StringJoiner("&");
            for (Map.Entry<String, String> entry : data.entrySet()) {
                postData.add(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) + "=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
            }

            URLConnection connection = new URL(url).openConnection();
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
            writer.write(postData.toString());
            writer.flush();

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            return response.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getMD5Hash(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashInBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));

            StringBuilder sb = new StringBuilder();
            for (byte b : hashInBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        // 实例化对象
        BtApiHttp api = new BtApiHttp("http://121.xx.xxx.64:xxxx", "xxxxxxxxxxxxxxxxxxxx");

        // 获取面板日志
        String logs = api.getLogs();

        // 输出结果到控制台
        System.out.println(logs);
    }
}
BtApiHttps.java:
import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

public class BtApiHttps {
    private String BT_KEY; // 接口密钥
    private String BT_PANEL; // 面板地址

    // 如果希望多台面板,可以在实例化对象时,将面板地址与密钥传入
    public BtApiHttps(String btPanel, String btKey) {
        if (btPanel != null) BT_PANEL = btPanel;
        if (btKey != null) BT_KEY = btKey;
    }

    // 示例取面板日志
    public String getLogs() {
        // 拼接URL地址
        String url = BT_PANEL + "/data?action=getData";
        //String url = BT_PANEL + "/system?action=GetSystemTotal";

        // 准备POST数据
        Map<String, String> pData = getKeyData(); // 取签名
        pData.put("table", "logs");
        pData.put("limit", "10");
        pData.put("tojs", "test");

        // 请求面板接口
        return httpPost(url, pData);
    }

    // 构造带有签名的关联数组
    private Map<String, String> getKeyData() {
        long nowTime = System.currentTimeMillis() / 1000;
        String requestToken = getMD5Hash(nowTime + getMD5Hash(BT_KEY));
        Map<String, String> pData = new HashMap<>();
        pData.put("request_token", requestToken);
        pData.put("request_time", String.valueOf(nowTime));
        return pData;
    }


    // 发起HTTPS POST请求
    private String httpPost(String url, Map<String, String> data) {
        try {
            trustAllCertificates(); // 调用信任所有证书的方法

            StringJoiner postData = new StringJoiner("&");
            for (Map.Entry<String, String> entry : data.entrySet()) {
                postData.add(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) + "=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
            }

            HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
            writer.write(postData.toString());
            writer.flush();

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            return response.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // 信任所有证书的方法
    private void trustAllCertificates() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }

                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        }

                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        }
                    }
            };

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        // 读取证书文件
        String certPath = "D:/20201008072/baota_root.pem";
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream(certPath));

        // 创建 TrustManagerFactory,加载证书
        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load(null, null);
        keystore.setCertificateEntry("myserver", cert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keystore);

        // 创建 SSLContext 并初始化 TrustManager
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        // 实例化对象
        BtApiHttps api = new BtApiHttps("https://121.43.xxx.xx:15220", "xxxxxxxxxxxxxxxxxxxx");

        // 获取面板日志
        String logs = api.getLogs();

        // 输出结果到控制台
        System.out.println(logs);
    }

    private String getMD5Hash(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashInBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));

            StringBuilder sb = new StringBuilder();
            for (byte b : hashInBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}

系统状态相关接口:https://www.bt.cn/data/api-doc.pdf

下面的DEMO只展示部分接口示例:

BtApiHttpsGetSystemTotal:
import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

public class BtApiHttpsGetSystemTotal {
    private String BT_KEY; // 接口密钥
    private String BT_PANEL; // 面板地址

    public BtApiHttpsGetSystemTotal(String btPanel, String btKey) {
        if (btPanel != null) BT_PANEL = btPanel;
        if (btKey != null) BT_KEY = btKey;
    }

    //获取日志信息
    public String getLogs() {
        String url = BT_PANEL + "/data?action=getData";

        Map<String, String> pData = getKeyData();
        pData.put("table", "logs");
        pData.put("limit", "10");
        pData.put("tojs", "test");

        return httpPost(url, pData);
    }

    //获取系统基础统计
    public String getSystemStats() {
        String url = BT_PANEL + "/system?action=GetSystemTotal";

        Map<String, String> pData = getKeyData();

        return httpPost(url, pData);
    }

    //获取磁盘分区信息
    public String GetDiskInfo(){
        String url = BT_PANEL + "/system?action=GetDiskInfo";
        Map<String, String> pData = getKeyData();
        return httpPost(url, pData);
    }

    //获取实时状态信息(CPU、内存、网络、负载)
    public String GetNetWork(){
        String url = BT_PANEL + "/system?action=GetNetWork";
        Map<String, String> pData = getKeyData();
        return httpPost(url, pData);
    }

    //检查是否有安装任务
    public String GetTaskCount(){
        String url = BT_PANEL + "/ajax?action=GetTaskCount";
        Map<String, String> pData = getKeyData();
        return httpPost(url, pData);
    }

    //检查面板更新
    public String UpdatePanel() {
        String url = BT_PANEL + "/ajax?action=UpdatePanel";

        Map<String, String> pData = getKeyData();
        pData.put("check", "true");    //强制检查更新 [可选]
        pData.put("force", "true");    //执行更新 [可选]
        return httpPost(url, pData);
    }

    //获取网站列表
    public String getDataTable() {
        String url = BT_PANEL + "/data?action=getData&table=sites";

        Map<String, String> pData = getKeyData();
        pData.put("p", "1");                //当前分页 [可选]
        pData.put("limit", "15");           //取回的数据行数 [必传]
        pData.put("type", "1");             //分类标识, -1: 分部分类 0: 默认分类 [可选]
        pData.put("order", "id desc");      //排序规则 使用 id 降序:id desc 使用名称升序:name desc [可选]
        pData.put("tojs", "get_site_list"); //分页 JS 回调,若不传则构造 URI 分页连接 [可选]
        pData.put("search", "www");         //搜索内容
        return httpPost(url, pData);
    }

    //删除网站
    public String DeleteSite() {
        String url = BT_PANEL + "/site?action=DeleteSite";

        Map<String, String> pData = getKeyData();
        pData.put("id", "66");              //网站 ID [必传]
        pData.put("webname", "w2_hao_com"); //网站名称 [必传]
        pData.put("ftp", "1");              //是否删除关联 FTP ,如果不删除请不要传此参数[可选]
        pData.put("database", "1");         //是否删除关联数据库,如果不删除请不要传此参数[可选]
        pData.put("path", "1");             //是否删除网站根目录,如果不删除请不要传此参数[可选]
        return httpPost(url, pData);
    }

    //停用网站
    public String SiteStop() {
        String url = BT_PANEL + "/site?action=SiteStop";

        Map<String, String> pData = getKeyData();
        pData.put("id", "66");              //网站 ID [必传]
        pData.put("webname", "w2_hao_com"); //网站名称 [必传]
        return httpPost(url, pData);
    }

    private Map<String, String> getKeyData() {
        long nowTime = System.currentTimeMillis() / 1000;
        String requestToken = getMD5Hash(nowTime + getMD5Hash(BT_KEY));
        Map<String, String> pData = new HashMap<>();
        pData.put("request_token", requestToken);
        pData.put("request_time", String.valueOf(nowTime));
        return pData;
    }

    private String httpPost(String url, Map<String, String> data) {
        try {
            trustAllCertificates();

            StringJoiner postData = new StringJoiner("&");
            for (Map.Entry<String, String> entry : data.entrySet()) {
                postData.add(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8) + "=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
            }

            HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());
            writer.write(postData.toString());
            writer.flush();

            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            return response.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private void trustAllCertificates() {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }

                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        }

                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        }
                    }
            };

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String certPath = "D:/20201008072/baota_root.pem";
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(new FileInputStream(certPath));

            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
            keystore.load(null, null);
            keystore.setCertificateEntry("myserver", cert);
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(keystore);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, tmf.getTrustManagers(), null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

            BtApiHttpsGetSystemTotal api = new BtApiHttpsGetSystemTotal("https://121.43.xxx.xx:15220", "xxxxxxxxxxxxxxxxxxxx");

            String logs = api.getLogs();
            String systemStats = api.getSystemStats();
            String DiskInfo = api.GetDiskInfo();
            String NetWork = api.GetNetWork();
            String TaskCount = api.GetTaskCount();
            String UpdatePanel = api.UpdatePanel();
            String DataTable = api.getDataTable();
            String DeleteSite = api.DeleteSite();
            String SiteStop = api.SiteStop();

            System.out.println("Logs: " + logs);                   //打印日志信息
            System.out.println("System Stats: " + systemStats);    //打印系统统计信息
            System.out.println("GetDiskInfo: " + DiskInfo);        //打印磁盘分区信息
            System.out.println("GetNetWork: " + NetWork);          //打印时状态信息(CPU、内存、网络、负载)
            System.out.println("GetTaskCount: " + TaskCount);      //检查是否有安装任务
            System.out.println("UpdatePanel: " + UpdatePanel);     //检查面板更新
            System.out.println("GetDataTable: " + DataTable);      //获取网站列表
            System.out.println("DeleteSite: " + DeleteSite);       //删除网站
            System.out.println("SiteStop: " + SiteStop);           //停用网站

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String getMD5Hash(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashInBytes = md.digest(input.getBytes(StandardCharsets.UTF_8));

            StringBuilder sb = new StringBuilder();
            for (byte b : hashInBytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值