当前位置: 首页 > 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…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...