• flask 添加用户认证API , 客户端用户认证


    flask 添加用户认证API , python 客户端用户认证

    flask blog 演示项目

    Documentation = https://flask.palletsprojects.com/tutorial/
    中文Documentation = https://flask.net.cn/
    源码 https://github.com/pallets/flask/tree/main/examples/tutorial

    修改 auth.py 添加用户认证API

    ### web 访问授权验证 
    @bp.route("/author", methods=("GET", "POST"))
    def author():
        """author a user is registered or not"""
    
        ret = -1
    
        if request.method == "POST":
            username = request.form["username"]
            password = request.form["password"]
            db = get_db()
            
            user = db.execute(
                "SELECT * FROM user WHERE username = ?", (username,)
            ).fetchone()
    
            if user is None:
                ret = 1 # "Incorrect username."
            elif not check_password_hash(user["password"], password):
                ret = 2 #"Incorrect password."
    
            if ret is -1:
                ret = 0  # "author OK"
    
        jsonRet={
            "status":ret,
            "value":ret
        }
    
        return jsonRet 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    client.py 访问 网站 获取认证结果

    其中 url = “http://127.0.0.1:5000/auth/author” 替换为实际的 flask服务器地址
    我这里在本机演示,所以是"http://127.0.0.1:5000/auth/author"

    import requests
    import json
    from typing import Tuple
    
    import getpass
    
    def author(username: str, password: str) -> Tuple[bool, str]:
        # 将此URL替换为您要登录的网站的URL
        url = "http://127.0.0.1:5000/auth/author"
        payload = {
            "username": username,
            "password": password
        }
        
        response :requests.Response = requests.post(url, data=payload, headers={"Referer": url})  # 模拟浏览器登陆过程
    
        print(f"response.url: {response.url}") 
        print(f"response.content: {response.content}")
        print(f"response.status_code: {response.status_code}")
    
        json_data = json.loads(response.content)
        status = json_data["status"]
        value = json_data["value"]
        print(f"status : {status}")
        print(f"value : {value}")
    
        if status == 0:
            return {True,"author OK"}
        else:
            return {False,"author Error"}
    
    username = input("请输入用户名:")
    # password = input("请输入密码:")
    password = getpass.getpass("请输入密码:")
    
    ret,message = author(username, password)
    print(f"{ret} {message}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    测试

    我这网站用户提前添加
    用户名 wmx
    密码 123

    测试,运行client.py

    wmx 123 验证正确:

    请输入用户名:wmx
    请输入密码:
    response.url: http://127.0.0.1:5000/auth/author
    response.content: b'{\n  "status": 0,\n  "value": 0\n}\n'
    response.status_code: 200
    status : 0
    value : 0
    True author OK
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ad ad 验证失败:

    请输入用户名:ad
    请输入密码:
    http://127.0.0.1:5000/auth/author
    b'{\n  "status": 1,\n  "value": 1\n}\n'
    200
    status : 1
    value : 1
    False author Error
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    c++ 客户端认证

    使用 curl 库 ,参考 mingw 编译 curl ,Qt 工程使用
    cJSON 库 ,参考 https://github.com/DaveGamble/cJSON

    
    #include 
    #include 
    #include 
    
    // libcurl回调函数,用于处理接收到的大量数据
    size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
        std::string *str = static_cast<std::string*>(userp);
        str->append((char*)contents, size * nmemb);
        return size * nmemb;
    }
    
    std::string post(const std::string& url, const std::string& username, const std::string& password) {
        CURL *curl = curl_easy_init();
        if(curl) {
            std::string buffer;
    
            struct curl_slist *headers = NULL;
            headers = curl_slist_append(headers, ("Referer:" + url).c_str() );
    
            curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    
            std::string postdata = "username=" + username + "&password=" + password;
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata.c_str());// "username=wmx&password=123"
    
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
            // 执行POST请求
            CURLcode res = curl_easy_perform(curl);
            if(res != CURLE_OK) {
                std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
            }
            // 清理
            curl_slist_free_all(headers);
            curl_easy_cleanup(curl);
            return buffer;
        } else {
            std::cerr << "curl_easy_init() failed" << std::endl;
            return "";
        }
    }
    
    ///解析JSON数据
    int  parseJson(const std::string& jsonStr) {
    
        int ret = -1;
    
        // 将JSON字符串转换为cJSON对象
        cJSON* json = cJSON_Parse(jsonStr.c_str());
        // 检查解析是否成功
        if (json == nullptr) {
            std::cerr << "Failed to parse JSON" << std::endl;
            return ret;
        }
    
        cJSON *status=nullptr;
        cJSON *value=nullptr;
        status = cJSON_GetObjectItemCaseSensitive(json, "status");
        value = cJSON_GetObjectItemCaseSensitive(json, "value");
        if (cJSON_IsNumber(status))
        {
            printf("status: \"%d\"\n", status->valueint);
            ret = status->valueint;
        }
        if (cJSON_IsNumber(value))
        {
            printf("value: \"%d\"\n", value->valueint);
        }
    
        // 释放cJSON对象的内存
        cJSON_Delete(json);
    
        return ret;
    }
    
    
    int main(int argc ,char**argv) {
    
        std::string url = "http://127.0.0.1:5000/auth/author"; // 替换为你要访问的URL   http://example.com
        std::string username = "wmx"; // 替换为你的用户名
        std::string password = "123"; // 替换为你的密码
        std::string response = post(url, username, password);
        if(!response.empty()) {
            int ret = parseJson(response);
            std::cout << response << std::endl;
            std::string msg = ret==0?"web author OK" :"web author error";
            std::cout <<msg<< std::endl;
        } else {
            std::cerr << "Empty response" << std::endl;
        }
        return 0;
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
  • 相关阅读:
    LCR 169.招式拆解 II
    Bytebase数据库 Schema 变更管理工具
    基于JAVA网络教学系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
    【前端实例代码】使用 HTML CSS 和 JavaScript 制作一个响应式搜索栏
    前端工作小结33-确定需求报告
    python链接数据库并创建/删除/插入多个数据库/表/表数据
    算法-- 爬楼梯(Kotlin)
    Python机器学习 | AI芯片调研
    CockroachDB-备份与恢复(1)备份架构
    Eureka服务注册中心
  • 原文地址:https://blog.csdn.net/WMX843230304WMX/article/details/132835310