官方地址:https://nsq.io/components/nsqd.html#auth
注意:官方只有 py 的 golang 的自己寫吧 (上面這個地址最上面描述了其他的一些接口和命令,有其他需要的自己看看)
原理解釋:
- 鑒權(quán)自己去第三方實現(xiàn)(需要實現(xiàn)它固定的幾個接口即可)
- 用 http 接口的實現(xiàn)
- 鑒權(quán)邏輯自己定
- nsq 開啟鑒權(quán)后,連接自動會請求你設(shè)置的地址對應(yīng)的接口,從而達(dá)到鑒權(quán)的目的,所以需要實現(xiàn)上面說的接口
實現(xiàn)例子1
第一步.準(zhǔn)備 golang 接口,編譯運行
// 接受 nsq 請求過來的參數(shù)
type AuthReq struct {
RemoteIP string `json:"remote_ip" form:"remote_ip"`
TLS bool `json:"tls" form:"tls"`
Secret string `json:"secret" form:"secret"`
CommonName string `json:"common_name" form:"common_name"`
}
type Authorization struct {
Topic string `json:"topic"` // 內(nèi)容需要是符合正則表達(dá)式的形勢,別問為啥,官方定的
Channels []string `json:"channels"` // 內(nèi)容需要是符合正則表達(dá)式的形勢
Permissions []string `json:"permissions"` // 訂閱或者發(fā)布 subscribe | publish
}
// 反饋給 nsq 的結(jié)構(gòu),參照官方的例子結(jié)構(gòu),https://nsq.io/components/nsqd.html#auth
type AuthResp struct {
TTL int `json:"ttl"` // 過期時間
Authorizations []Authorization `json:"authorizations"` // 允許(或者不允許)哪些主體和通道
Identity string `json:"identity"` // 身份
IdentityURL string `json:"identity_url"` // 身份地址,就是提供驗證的接口地址,例如這里本地的就是就是 127.0.0.1:1325
Expires time.Time
}
func main() {
g := APIRoute()
g.Run(":1325")
}
func APIRoute() *gin.Engine {
r := gin.Default()
r.GET("/ping", ping)
r.GET("/auth", auth) // 鑒權(quán)的接口,nsq 使用了 auth-http-address 參數(shù)后,連接到 nsq 會自動請求這個接口
return r
}
func ping(c *gin.Context) { c.JSON(http.StatusOK, "pong") }
// 請求到該接口后,自定義權(quán)限邏輯
func auth(c *gin.Context) {
req := &AuthReq{}
err := c.Bind(req)
if err != nil {
log.Println(err)
return
}
// 這里做你自己的密碼邏輯判斷,這里只是做了一個空值的判斷而已
if req.Secret == "" {
c.JSON(http.StatusForbidden, gin.H{
"message": "NOT_AUTH",
})
return
}
res := AuthResp{
TTL: 60,
Identity: "your name",
IdentityURL: "http://127.0.0.1:1325",
Authorizations: []Authorization{
{
Topic: ".*", // 這里設(shè)置全部可以,如果指定哪些 Topic 可以,在這里反饋即可,比如指定 “test”,那就該連接只能操作 test 的 topic
Channels: []string{".*"}, // 這個同上
Permissions: []string{
"subscribe",
"publish"},
},
},
}
log.Println("req:", res)
c.JSON(http.StatusOK, res)
}
第二步,準(zhǔn)備 nsq(使用 docker )
注意這里的地址,172.17.0.2 可能改成你自己的 lookupd 網(wǎng)段地址,自己進(jìn)入容器查
docker pull nsqio/nsq
docker run -d --name lookupd -p 4160:4160 -p 4161:4161 nsqio/nsq /nsqlookupd
docker run -d --name nsqd -p 4150:4150 -p 4151:4151 nsqio/nsq /nsqd --broadcast-address=172.17.0.2 --lookupd-tcp-address=172.17.0.2:4160 -auth-http-address="192.168.31.35:1325"
docker run -d --name nsqadmin -p 4171:4171 nsqio/nsq /nsqadmin --lookupd-http-address=172.17.0.2:4161
第三步,另外啟一個項目,代碼加入鑒權(quán)連接
func main() {
if _, err := NewNsqCustomer("127.0.0.1:4150", "topic_test", channel_test", &nsqHandler{nsqHandlerID: "three"}); err != nil {
log.Println("err:", err)
return
}
}
func NewNsqCustomer(tcpNsqdAddrr, topic, channel string, handle interface{}) (*nsq.Consumer, error) {
conf := nsq.NewConfig()
conf.AuthSecret = "12345678"
conf.Hostname = "stb"
con, err := nsq.NewConsumer(topic, channel, conf)
if err != nil {
return nil, err
}
// // defer con.Stop()
hd, ok := handle.(nsq.Handler)
if !ok {
return nil, errors.New("handle type error")
}
con.AddHandler(hd)
err = con.ConnectToNSQD(tcpNsqdAddrr)
if err != nil {
return nil, err
}
return con, nil
}
四,編譯運行就能看到上面 1325 那邊接收到請求了

image.png