Nostr账号Nip05验证方法

最近Damus App很火,写一篇教程教大家如何在App中获得紫v图标认证。

NIP是Nostr改进提议Nostr Improvement ProposalNIP05描述了一种账号验证方法。可以想象成telegram或者twitter上的蓝色V标记,在Damus里是一个紫V图标,客户端展示这个图标,就说明该用户通过了NIP05验证。

该验证由客户端发起,当发现用户设置了用户名和NIP05验证地址,会发送一个https请求。

比如用户名kirito和验证地址kirito@dogdogback.com,客户端会发送如下请求:

1
https://dogdogback.com/.well-known/nostr.json?name=kirito

如果验证成功,dogdogback.com应该返回如下结果:

1
2
3
4
5
{
  "names": {
    "kirito": "2f7caa968b0ec9bacd55a07cfaf6206aab5a62387c76303c311db949dec8bc57"
  }
}

你也可以调用这个请求观察下返回: https://dogdogback.com/.well-known/nostr.json?name=kirito

客户端对比返回结果里的公钥和用户的公钥,如果一致则验证完成,Damus会在你头像后展示紫V图标。

https://blog-1256556944.file.myqcloud.com/public/nostr/%E7%B4%ABv.jpg

有两种路线:

  1. 找提供验证服务的社区项目,直接用他们的服务,这个自己找吧,缺点是可能不稳定,也不受自己控制
  2. 用自己的域名进行验证,前提是你拥有一个域名的控制权,本文主要讲解这种方式

如果你已经有自己的网站了,并且支持https,那么直接在你的网站根目录放置一个静态文件即可。 文件名为.well-known/nostr.json,内容写上你的用户名和公钥:

1
2
3
4
5
{
  "names": {
    "kirito": "2f7caa968b0ec9bacd55a07cfaf6206aab5a62387c76303c311db949dec8bc57"
  }
}

可以写多行,为你的小伙伴也提供验证。

当然有更好的方式,而且不需要服务器和证书,下面介绍下我使用的方式:vercel云函数(你自己会搭服务或者有其他云函数也行,原理一样)

我之前写过一篇怎么用vercel云函数的文章,可以参考,当你弄好后,绑定自己的域名,就可以通过自己的域名访问云函数了,这是一个例子: https://dogdogback.com/api/list

代码如果不会写直接克隆我的仓库即可vercel-faas

具体操作:

  1. 修改代码仓库中的文件vercel.json,添加NIP05接口的重定向,这样访问路径/.well-known/nostr.json?name=xxx的请求会被交给/api/entrypoint.go文件处理:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    {
    "trailingSlash": false,
    "rewrites":
    [
        {
        "source": "/api/(.*)",
        "destination": "/api/entrypoint.go"
        },
        {
        "source": "/.well-known/nostr.json",
        "destination": "/api/entrypoint.go"
        }
    ]
    }
    
  2. 添加处理认证请求的路由,修改/api/entrypoint.go
    1
    2
    3
    4
    
    func registerRouter(r *gin.RouterGroup) {
        // ...
        r.GET("/.well-known/nostr.json", handler.Cors, handler.NIP05)
    }
    
  3. 添加认证逻辑,修改/handler/handler.go:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    
    func NIP05(c *gin.Context) {
        name2pubkey := map[string]string{
            "kirito": "2f7caa968b0ec9bacd55a07cfaf6206aab5a62387c76303c311db949dec8bc57",
            // 可以在这里添加更多的账号,为你的朋友提供验证
            // "<name1>":"pubkey1",
            // "<name2>":"pubkey2",
        }
        user := c.Query("name")
        fmt.Println("nip05 verify request", user)
        if v, ok := name2pubkey[user]; ok {
            resp := NIP05Resp{}
            resp.Names[user] = v
            c.JSON(http.StatusOK, resp)
        }
        c.Status(http.StatusNotFound)
        return
    }
    

把代码push到你的仓库,vercel会自动重新部署,然后用你的域名访问看看效果,这是我的:

  1. https://dogdogback.com/.well-known/nostr.json?name=kirito
  2. https://dogdogback.com/.well-known/nostr.json?name=shishi

以Damus举例,编辑资料,配置你的用户名和NIP05地址,就可以看到紫V图标了

https://blog-1256556944.file.myqcloud.com/public/nostr/set-name.jpg
https://blog-1256556944.file.myqcloud.com/public/nostr/set-nip05.jpg

到这里就成功了,有疑问可以评论区提。

  1. 有些webapp请求是会受到浏览器跨域策略限制,在http返回header中设置Access-Control-Allow-Origin: *,我的代码中已经处理了,如果用静态文件的方式无法处理跨域。
  2. 如何获取hex格式的公钥?在Damus中长按你自己发送的信息,选择Copy Note JSON然后粘贴到一个地方,就能看到了。
  3. vercel也是可以托管静态文件的,仓库里只留一个json文件就行。
  4. 富哥V我50