当前位置: 首页 > news >正文

golang通过参数控制HTTP server是否使用基本认证

之前写的《golang实现一个BasicAuth的HTTP server》一定会做基本认证。
本例给出了如何通过启动时候指定的参数来控制是否做基本认证

代码对比和解释

  • 给出与上一篇中源码的diff
admin@hpc-1:~/go/auth_http$ diff -ruN http_rpc_server.go_bak http_rpc_server.go
--- http_rpc_server.go_bak      2024-03-21 16:53:58.899582234 +0800
+++ http_rpc_server.go  2024-03-21 17:51:01.878115766 +0800
@@ -11,7 +11,9 @@// 定义一个用于接收请求的结构体
-type MapPrinter struct{}
+type MapPrinter struct{
+    AuthEnabled bool
+}// 定义一个用于接收请求的方法func (m *MapPrinter) PrintMap(w http.ResponseWriter, r *http.Request) {
@@ -19,23 +21,26 @@http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)return}
-    // 检查认证头部信息
-    username, password, ok := r.BasicAuth()
-    if !ok {
-        // 未提供基本身份验证,返回 401 Unauthorized
-        w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
-        w.WriteHeader(http.StatusUnauthorized)
-        fmt.Fprintln(w, "401 Unauthorized")
-        return
-    }
-    
-    // 验证用户名和密码
-    if !utils.CheckCredentials(username, password) {
-        // 用户名和密码不匹配,返回 401 Unauthorized
-        w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
-        w.WriteHeader(http.StatusUnauthorized)
-        fmt.Fprintln(w, "401 Unauthorized")
-        return
+    // 检查是否启用了基本认证
+    if m.AuthEnabled {
+        // 检查认证头部信息
+        username, password, ok := r.BasicAuth()
+        if !ok {
+            // 未提供基本身份验证,返回 401 Unauthorized
+            w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
+            w.WriteHeader(http.StatusUnauthorized)
+            fmt.Fprintln(w, "401 Unauthorized")
+            return
+        }
+        
+        // 验证用户名和密码
+        if !utils.CheckCredentials(username, password) {
+            // 用户名和密码不匹配,返回 401 Unauthorized
+            w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
+            w.WriteHeader(http.StatusUnauthorized)
+            fmt.Fprintln(w, "401 Unauthorized")
+            return
+        }}var payload map[string]interface{}
@@ -57,11 +62,18 @@func main() {//获取监听端口,默认8080port := flag.String("p", "8080", "指定监听端口")
+    //获取是否使能认证,默认不使能
+    authEnabled := flag.Bool("a", false, "Enable basic authentication")// 解析命令行参数flag.Parse()+    // 创建RPC服务实例
+    rpcService := &MapPrinter{
+        AuthEnabled: *authEnabled, // 根据命令行参数设置是否启用基本认证
+    }
+//注册abc-api路由
-    http.HandleFunc("/abc-api", new(MapPrinter).PrintMap)
+    http.HandleFunc("/abc-api", rpcService.PrintMap)fmt.Println("Server is listening on port %s...", *port)log.Fatal(http.ListenAndServe(":" + *port, nil))
admin@hpc-1:~/go/auth_http$ 
  • 解释
    • 定义的结构体MapPrinter增加一个bool属性AuthEnabled ,用来控制是否做基本认证
    • 之前代码中做认证的部分,只有当AuthEnabled为true的时候才执行
    • 通过flag提取-a后面跟着的true或是false用来给AuthEnabled 赋值,默认为false
    • 创建实例rpcService的时候,将flag获取的值赋给AuthEnabled
    • 注册路由的时候,直接关联到实例rpcService
  • 完整源码
admin@hpc-1:~/go/auth_http$ cat http_rpc_server.go
package mainimport ("fmt""log""flag""net/http""encoding/json""my_auth/utils"
)// 定义一个用于接收请求的结构体
type MapPrinter struct{AuthEnabled bool
}// 定义一个用于接收请求的方法
func (m *MapPrinter) PrintMap(w http.ResponseWriter, r *http.Request) {if r.Method != http.MethodPost {http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)return}// 检查是否启用了基本认证if m.AuthEnabled {// 检查认证头部信息username, password, ok := r.BasicAuth()if !ok {// 未提供基本身份验证,返回 401 Unauthorizedw.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)w.WriteHeader(http.StatusUnauthorized)fmt.Fprintln(w, "401 Unauthorized")return}// 验证用户名和密码if !utils.CheckCredentials(username, password) {// 用户名和密码不匹配,返回 401 Unauthorizedw.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)w.WriteHeader(http.StatusUnauthorized)fmt.Fprintln(w, "401 Unauthorized")return}}var payload map[string]interface{}err := json.NewDecoder(r.Body).Decode(&payload)if err != nil {http.Error(w, "Invalid payload", http.StatusBadRequest)return}fmt.Println("Received payload:")for key, value := range payload {fmt.Printf("%s: %v\n", key, value)}w.WriteHeader(http.StatusOK)w.Write([]byte("Map printed successfully\n"))
}func main() {//获取监听端口,默认8080port := flag.String("p", "8080", "指定监听端口")//获取是否使能认证,默认不使能authEnabled := flag.Bool("a", false, "Enable basic authentication")// 解析命令行参数flag.Parse()// 创建RPC服务实例rpcService := &MapPrinter{AuthEnabled: *authEnabled, // 根据命令行参数设置是否启用基本认证}//注册abc-api路由http.HandleFunc("/abc-api", rpcService.PrintMap)fmt.Println("Server is listening on port %s...", *port)log.Fatal(http.ListenAndServe(":" + *port, nil))
}
admin@hpc-1:~/go/auth_http$ 

验证

不使能认证

  • 运行时候不指定-a,或者 -a=false,注意,不能使用"-a false",否则一直是true!
admin@hpc-1:~/go/auth_http$ ./http_rpc_server -p 8090 -a=false
Server is listening on port %s... 8090
  • 另开终端,无论是不带basic auth header还是随便带什么basic authen header,都可以正常提供服务
admin@hpc-1:~$ curl -X POST  -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
Map printed successfully
admin@hpc-1:~$ 
admin@hpc-1:~$ curl -X POST -u admin:admin -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
Map printed successfully
admin@hpc-1:~$ 

使能认证

  • 运行时指定-a=true
admin@hpc-1:~/go/auth_http$ ./http_rpc_server -p 8090 -a=true
Server is listening on port %s... 8090
  • 无论是不带基础认证或者是用户名密码不匹配,都会报错
admin@hpc-1:~$ curl -X POST  -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
401 Unauthorized
admin@hpc-1:~$ 
admin@hpc-1:~$ curl -X POST -u admin:nimda -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
401 Unauthorized
admin@hpc-1:~$ 
  • 只有带正确的用户名密码认证的请求才会被正确处理
admin@hpc-1:~$ curl -X POST -u admin:admin -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://localhost:8090/abc-api
Map printed successfully
admin@hpc-1:~$ 

额外知识点

  • flag的参数,即可以用空格也可以用=连接flag和赋值(-p=8090 和 -p 8090等价)
  • 只有bool类型是例外,只能是用=
本例中,默认指定authEnabled 为false下面用法表示false
(1)$ ./http_rpc_server -p=8090 -a=false
(2)$ ./http_rpc_server -p=8090 下面用法表示true
(1)$ ./http_rpc_server -p=8090 -a=true
(2)$ ./http_rpc_server -p=8090 -a
(3) ./http_rpc_server -p=8090 -a <随便什么非空格字符,甚至可以是false>

相关文章:

golang通过参数控制HTTP server是否使用基本认证

之前写的《golang实现一个BasicAuth的HTTP server》一定会做基本认证。 本例给出了如何通过启动时候指定的参数来控制是否做基本认证 代码对比和解释 给出与上一篇中源码的diff adminhpc-1:~/go/auth_http$ diff -ruN http_rpc_server.go_bak http_rpc_server.go --- http_rp…...

javaSwing坦克大战游戏

在游戏开发领域&#xff0c;坦克大战是一款经典的游戏&#xff0c;其简单而又耐玩的玩法吸引了无数玩家。而今&#xff0c;在Java编程技术的支持下&#xff0c;我们可以用Java Swing技术轻松实现这款经典游戏。本文将介绍如何使用Java Swing技术编写坦克大战游戏&#xff0c;并…...

【面试题】数据底层原理:Elasticsearch写入流程解析

前言&#xff1a;本篇博客将介绍Elasticsearch的数据底层原理&#xff0c;涉及数据写入的过程以及相关概念。我们将深入探讨buffer、translog、refresh、commit、flush和merge等核心概念&#xff0c;帮助您更好地理解Elasticsearch的数据存储机制。 写入数据的基本过程 Elast…...

牛客论坛spring initializer选用的构件

spring版本&#xff1a;2.1.5.RELEASE java版本&#xff1a;8 pom文件&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-i…...

【Java程序设计】【C00385】基于(JavaWeb)Springboot的员工信息管理系统(有论文)

基于&#xff08;JavaWeb&#xff09;Springboot的员工信息管理系统 项目简介项目获取开发环境项目技术运行截图 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c…...

【Linux进阶之路】理解UDP,成为TCP。

前言 学了TCP 和UDP之后&#xff0c;感觉UDP就像是初入职场的年轻人&#xff0c;两耳不闻 “窗外事”&#xff0c;只管尽力地把自己的事情做好&#xff0c;但收获的却是不可靠&#xff0c;而TCP更像是涉世极深的"职场老油条"&#xff0c;给人的感觉就是 “城府极深&a…...

Linux实用操作

一&#xff0c;各类小技巧&#xff08;快捷键&#xff09; 强制停止 ctrlc强制停止 Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以使用快捷键ctrlc 命令输入错误,也可以通过快捷键ctrlc,退出当前输入,重新输入 退出、登出 ctrld退出或登出 可以通过快…...

OpenJudge - 12:加密的病历单

总时间限制: 1000ms 内存限制: 65536kB 描述 小英是药学专业大三的学生&#xff0c;暑假期间获得了去医院药房实习的机会。 在药房实习期间&#xff0c;小英扎实的专业基础获得了医生的一致好评&#xff0c;得知小英在计算概论中取得过好成绩后&#xff0c;主任又额外交给她一…...

QGIS编译(跨平台编译)057:FastCGI编译(Windows、Linux、MacOS环境下编译)

文章目录 1、FastCGI介绍2、FastCGI下载3、Windows下编译4、linux下编译5、MacOS下编译1、FastCGI介绍 FCGI 是 FastCGI 的缩写,是一种用于改善 CGI(Common Gateway Interface)性能的协议。在传统的 CGI 中,每次请求都需要启动一个新的进程来处理,这导致了较高的资源消耗和…...

jenkins+newman+postman持续集成环境搭建

一、Newman简介 Newman是一款基于Node.js开发的&#xff0c;可以运用postman工具直接从命令运行和测试postman集合 二、Newman应用 环境准备&#xff1a;js/ cnpm或npm配置好环境&#xff0c;执行如下命令 三、安装newman 验证是否安装成功&#xff0c;命令&#xff1a;newm…...

取消自动设置的开机自启动(pywin32库)请勿仿照!否则可能对电脑造成损害。

本文使用创作助手。 要取消Python程序的开机自启动&#xff0c;可以通过删除注册表中相应的注册表项来实现。请按照以下步骤进行操作&#xff1a; 打开Windows注册表编辑器&#xff1a;按下 Windows R 键&#xff0c;输入 regedit&#xff0c;然后按下回车键。 导航到注册表…...

金融投贷通(金融投资+贷款通)项目准备

金融投贷通&#xff08;金融投资贷款通&#xff09;项目准备 专业术语投资专业术语本息专业术语还款专业术语项目介绍三个子系统技术架构核心流程发布借款标投资业务 项目实施测试流程测试步骤 专业术语 投资专业术语 案例&#xff1a;张三借给李四5W&#xff0c;约定期满1年后…...

跟我学C++中级篇——STL的中的删除

一、介绍 在STL中一般删除的方式有两类&#xff0c;一种是使用全局的std::remove(remove_if类似)&#xff0c;一种是使用容器自带的erase&#xff0c;前者其实并没有真正的删除数据&#xff0c;而后者则是在移动时&#xff0c;会有一些细节的处理&#xff0c;否则要么程序崩溃…...

js如何遍历查询一个颗树

近段时间去面试的时候&#xff0c;被面试官问到如何遍历查询一个颗树的时候&#xff0c;可能最近自己看了数据结构的书之后&#xff0c;隐隐约约就想到二叉树的三种排序&#xff08;前序、中序、后序&#xff09;&#xff0c;但是当时自己没有想起这三种排序的名字&#xff0c;…...

【面试必备】针对一个案例,怎么测试

思考角度 测试用例设计万能公式功能测试&#xff08;最重要&#xff09;界面测试易用性测试性能测试安全性测试兼容性测试容错性测试 常见案例物品类水杯笔 软件类微信发送朋友圈功能 测试用例设计万能公式 在面试中经常会遇到的一类题是&#xff0c;给你一个具体的产品&#…...

vue3 hooks之事件广播(支持跨标签页)

/**** 同源下的全局事件总线&#xff0c;支持跨标签页通信* 第一步&#xff1a;注册事件* 第二步&#xff1a;广播事件* 第三步&#xff1a;处理事件*/// source&#xff1a;消息发起源href&#xff0c;将在跨标签页通信时传入 interface callback {(data: any, source: any): …...

go中validate包使用教程

文章目录 前言安装简单使用错误处理翻译器Validator库介绍校验语法常用标记自定义校验需求【校验车身颜色】前言 在go项目中,经常有校验数据合法性的需求,比如邮箱、年龄、车牌号、网址、字符串长度、金额、枚举范围等。一个好的校验包能帮我们少写很多ifelse,提高系统的可…...

canvas画带透明度的直线和涂鸦

提示&#xff1a;canvas画线 文章目录 前言一、带透明度的直线和涂鸦总结 前言 一、带透明度的直线和涂鸦 test.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content…...

linux命令 curl忽略https证书

curl https://www.baidu.com 会提示需要htttps证书&#xff0c;加 -k 即可&#xff0c;如下&#xff1a; curl -k https://www.baidu.com 如果要带头部&#xff0c;认证数据&#xff0c;加-H curl -s -k -H "Authorization: Bearer 651fasgassssgjage2" https:/…...

游戏引擎中网络游戏的基础

一、前言 网络游戏所面临的挑战&#xff1a; 一致性&#xff1a;如何在所有的主机内都保持一样的表现可靠性&#xff1a;网络传输有可能出现丢包安全性&#xff1a;反作弊&#xff0c;反信息泄漏。多样性&#xff1a;不同设备之间链接&#xff0c;比如手机&#xff0c;ipad&a…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

PHP和Node.js哪个更爽?

先说结论&#xff0c;rust完胜。 php&#xff1a;laravel&#xff0c;swoole&#xff0c;webman&#xff0c;最开始在苏宁的时候写了几年php&#xff0c;当时觉得php真的是世界上最好的语言&#xff0c;因为当初活在舒适圈里&#xff0c;不愿意跳出来&#xff0c;就好比当初活在…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...