无密码验证:服务器 | Linux 中国

2018 年 6 月 15 日 Linux中国
无密码验证可以让你只输入一个 email 而无需输入密码即可登入系统。这是一种比传统的电子邮件/密码验证方式登入更安全的方法。
-- Nicolás Parada



致谢
编译自 | https://nicolasparada.netlify.com/posts/passwordless-auth-server/ 
 作者 | Nicolás Parada
 译者 | qhwdw 🌟 🌟 🌟 🌟 🌟 共计翻译:117 篇 贡献时间:212 天

无密码验证可以让你只输入一个 email 而无需输入密码即可登入系统。这是一种比传统的电子邮件/密码验证方式登入更安全的方法。

下面我将为你展示,如何在 Go[1] 中实现一个 HTTP API 去提供这种服务。

流程

◈ 用户输入他的电子邮件地址。
◈ 服务器创建一个临时的一次性使用的代码(就像一个临时密码一样)关联到用户,然后给用户邮箱中发送一个“魔法链接”。
◈ 用户点击魔法链接。
◈ 服务器提取魔法链接中的代码,获取关联的用户,并且使用一个新的 JWT 重定向到客户端。
◈ 在每次有新请求时,客户端使用 JWT 去验证用户。

必需条件

◈ 数据库:我们为这个服务使用了一个叫  CockroachDB [2] 的 SQL 数据库。它非常像 postgres,但它是用 Go 写的。
◈ SMTP 服务器:我们将使用一个第三方的邮件服务器去发送邮件。开发的时我们使用  mailtrap [3]。Mailtrap 发送所有的邮件到它的收件箱,因此,你在测试时不需要创建多个假邮件帐户。

从 Go 的主页[4] 上安装它,然后使用 go version(1.10.1 atm)命令去检查它能否正常工作。

从 CockroachDB 的主页[5] 上下载它,展开它并添加到你的 PATH 变量中。使用 cockroach version(2.0 atm)命令检查它能否正常工作。

数据库模式

现在,我们在 GOPATH 目录下为这个项目创建一个目录,然后使用 cockroach start 启动一个新的 CockroachDB 节点:

   
   
     
  1. cockroach start --insecure --host 127.0.0.1

它会输出一些内容,找到 SQL 地址行,它将显示像 postgresql://root@127.0.0.1:26257?sslmode=disable 这样的内容。稍后我们将使用它去连接到数据库。

使用如下的内容去创建一个 schema.sql 文件。

   
   
     
  1. DROP DATABASE IF EXISTS passwordless_demo CASCADE;

  2. CREATE DATABASE IF NOT EXISTS passwordless_demo;

  3. SET DATABASE = passwordless_demo;

  4. CREATE TABLE IF NOT EXISTS users (

  5.    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

  6.    email STRING UNIQUE,

  7.    username STRING UNIQUE

  8. );

  9. CREATE TABLE IF NOT EXISTS verification_codes (

  10.    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),

  11.    user_id UUID NOT NULL REFERENCES users ON DELETE CASCADE,

  12.    created_at TIMESTAMPTZ NOT NULL DEFAULT now()

  13. );

  14. INSERT INTO users (email, username) VALUES

  15.    ('john@passwordless.local', 'john_doe');

这个脚本创建了一个名为 passwordless_demo 的数据库、两个名为 users 和 verification_codes 的表,以及为了稍后测试而插入的一些假用户。每个验证代码都与用户关联并保存创建时间,以用于去检查验证代码是否过期。

在另外的终端中使用 cockroach sql 命令去运行这个脚本:

   
   
     
  1. cat schema.sql | cockroach sql --insecure

环境配置

需要配置两个环境变量:SMTP_USERNAME 和 SMTP_PASSWORD,你可以从你的 mailtrap 帐户中获得它们。将在我们的程序中用到它们。

Go 依赖

我们需要下列的 Go 包:

◈  github.com/lib/pq [6]:它是 CockroachDB 使用的 postgres 驱动
◈  github.com/matryer/way [7]: 路由器
◈  github.com/dgrijalva/jwt-go [8]: JWT 实现
   
   
     
  1. go get -u github.com/lib/pq

  2. go get -u github.com/matryer/way

  3. go get -u github.com/dgrijalva/jwt-go

代码

初始化函数

创建 main.go 并且通过 init 函数里的环境变量中取得一些配置来启动。

   
   
     
  1. var config struct {

  2.    port        int

  3.    appURL      *url.URL

  4.    databaseURL string

  5.    jwtKey      []byte

  6.    smtpAddr    string

  7.    smtpAuth    smtp.Auth

  8. }

  9. func init() {

  10.    config.port, _ = strconv.Atoi(env("PORT", "80"))

  11.    config.appURL, _ = url.Parse(env("APP_URL", "http://localhost:"+strconv.Itoa(config.port)+"/"))

  12.    config.databaseURL = env("DATABASE_URL", "postgresql://root@127.0.0.1:26257/passwordless_demo?sslmode=disable")

  13.    config.jwtKey = []byte(env("JWT_KEY", "super-duper-secret-key"))

  14.    smtpHost := env("SMTP_HOST", "smtp.mailtrap.io")

  15.    config.smtpAddr = net.JoinHostPort(smtpHost, env("SMTP_PORT", "25"))

  16.    smtpUsername, ok := os.LookupEnv("SMTP_USERNAME")

  17.    if !ok {

  18.        log.Fatalln("could not find SMTP_USERNAME on environment variables")

  19.    }

  20.    smtpPassword, ok := os.LookupEnv("SMTP_PASSWORD")

  21.    if !ok {

  22.        log.Fatalln("could not find SMTP_PASSWORD on environment variables")

  23.    }

  24.    config.smtpAuth = smtp.PlainAuth("", smtpUsername, smtpPassword, smtpHost)

  25. }

  26. func env(key, fallbackValue string) string {

  27.    v, ok := os.LookupEnv(key)

  28.    if !ok {

  29.        return fallbackValue

  30.    }

  31.    return v

  32. }

◈  appURL 将去构建我们的 “魔法链接”。
◈  port 将要启动的 HTTP 服务器。
◈  databaseURL 是 CockroachDB 地址,我添加  /passwordless_demo 前面的数据库地址去表示数据库名字。
◈  jwtKey 用于签名 JWT。
◈  smtpAddr 是  SMTP_HOST +  SMTP_PORT 的联合;我们将使用它去发送邮件。
◈  smtpUsername 和  smtpPassword 是两个必需的变量。
◈  smtpAuth 也是用于发送邮件。

env 函数允许我们去获得环境变量,不存在时返回一个回退值。

主函数

   
   
     
  1. var db *sql.DB

  2. func main() {

  3.    var err error

  4.    if db, err = sql.Open("postgres", config.databaseURL); err != nil {

  5.        log.Fatalf("could not open database connection: %v\n", err)

  6.    }

  7.    defer db.Close()

  8.    if err = db.Ping(); err != nil {

  9.        log.Fatalf("could not ping to database: %v\n", err)

  10.    }

  11.    router := way.NewRouter()

  12.    router.HandleFunc("POST", "/api/users", jsonRequired(createUser))

  13.    router.HandleFunc("POST", "/api/passwordless/start", jsonRequired(passwordlessStart))

  14.    router.HandleFunc("GET", "/api/passwordless/verify_redirect", passwordlessVerifyRedirect)

  15.    router.Handle("GET", "/api/auth_user", authRequired(getAuthUser))

  16.    addr := fmt.Sprintf(":%d", config.port)

  17.    log.Printf("starting server at %s


登录查看更多
0

相关内容

【2020新书】实战R语言4,323页pdf
专知会员服务
100+阅读 · 2020年7月1日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
AI创新者:破解项目绩效的密码
专知会员服务
33+阅读 · 2020年6月21日
Python导论,476页pdf,现代Python计算
专知会员服务
259+阅读 · 2020年5月17日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【干货书】R语言书: 编程和统计的第一课程,
专知会员服务
111+阅读 · 2020年5月9日
Python分布式计算,171页pdf,Distributed Computing with Python
专知会员服务
107+阅读 · 2020年5月3日
【德勤】中国人工智能产业白皮书,68页pdf
专知会员服务
301+阅读 · 2019年12月23日
渗透某德棋牌游戏
黑白之道
12+阅读 · 2019年5月17日
Kali Linux 渗透测试:密码攻击
计算机与网络安全
16+阅读 · 2019年5月13日
支持多标签页的Windows终端:Fluent 终端
Python程序员
7+阅读 · 2019年4月15日
Github项目推荐 | pikepdf - Python的PDF读写库
AI研习社
9+阅读 · 2019年3月29日
深大教授开源的人脸检测库,速度号称史上最快
大数据技术
9+阅读 · 2019年3月21日
34个最优秀好用的Python开源框架
专知
9+阅读 · 2019年3月1日
C# 10分钟完成百度人脸识别
DotNet
3+阅读 · 2019年2月17日
超级!超级!超级好用的视频标注工具
极市平台
8+阅读 · 2018年12月27日
Arxiv
35+阅读 · 2019年11月7日
Bidirectional Attention for SQL Generation
Arxiv
4+阅读 · 2018年6月21日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
100+阅读 · 2020年7月1日
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
AI创新者:破解项目绩效的密码
专知会员服务
33+阅读 · 2020年6月21日
Python导论,476页pdf,现代Python计算
专知会员服务
259+阅读 · 2020年5月17日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
117+阅读 · 2020年5月10日
【干货书】R语言书: 编程和统计的第一课程,
专知会员服务
111+阅读 · 2020年5月9日
Python分布式计算,171页pdf,Distributed Computing with Python
专知会员服务
107+阅读 · 2020年5月3日
【德勤】中国人工智能产业白皮书,68页pdf
专知会员服务
301+阅读 · 2019年12月23日
相关资讯
渗透某德棋牌游戏
黑白之道
12+阅读 · 2019年5月17日
Kali Linux 渗透测试:密码攻击
计算机与网络安全
16+阅读 · 2019年5月13日
支持多标签页的Windows终端:Fluent 终端
Python程序员
7+阅读 · 2019年4月15日
Github项目推荐 | pikepdf - Python的PDF读写库
AI研习社
9+阅读 · 2019年3月29日
深大教授开源的人脸检测库,速度号称史上最快
大数据技术
9+阅读 · 2019年3月21日
34个最优秀好用的Python开源框架
专知
9+阅读 · 2019年3月1日
C# 10分钟完成百度人脸识别
DotNet
3+阅读 · 2019年2月17日
超级!超级!超级好用的视频标注工具
极市平台
8+阅读 · 2018年12月27日
Top
微信扫码咨询专知VIP会员