一、啥是 JWT 认证
JWT 就是 JSON Web Token 的缩写,简单来说,它是一种用于在网络应用间传递声明的安全方式。打个比方,你去一个高档小区,保安会给你一张临时通行证,这个通行证就好比 JWT。小区居民(客户端)拿着这张通行证(JWT),就能在小区里自由活动(访问 API)。
JWT 一般由三部分组成,分别是头部(Header)、载荷(Payload)和签名(Signature)。头部主要说明这个 JWT 用的是什么算法;载荷就是包含一些用户信息,像用户名、角色啥的;签名则是用来验证这个 JWT 的真实性。
二、OpenResty 是个啥
OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,它把很多 Nginx 模块集成在一起,让开发者能轻松地用 Lua 脚本扩展 Nginx 的功能。就好比你有一把普通的菜刀,OpenResty 给这把菜刀装上了各种不同的刀头,让它能切菜、切肉还能雕花。
OpenResty 有很多优点,它性能高,能处理大量并发请求;开发起来也方便,用 Lua 脚本就能快速实现各种功能。
三、为啥要用 OpenResty 实现 JWT 认证
应用场景
在很多 Web 应用里,API 的安全访问控制非常重要。比如说一个电商平台,用户登录后要访问自己的订单信息、修改个人资料等,这些操作都需要进行身份验证。用 OpenResty 实现 JWT 认证,就能很好地控制用户对 API 的访问。
技术优缺点
优点
- 高性能:OpenResty 基于 Nginx,能处理大量并发请求,响应速度快。就像一个高效的交通指挥系统,能让车辆(请求)快速通过。
- 灵活性:用 Lua 脚本可以灵活地实现各种认证逻辑,开发者可以根据自己的需求定制。
- 跨平台:可以在不同的操作系统上运行,兼容性好。
缺点
- 学习成本:对于没有 Lua 基础的开发者来说,可能需要花一些时间学习 Lua 语言。
- 调试难度:由于涉及到 Nginx 和 Lua,调试起来可能会比较复杂。
注意事项
- 要妥善保管好 JWT 的密钥,一旦密钥泄露,整个认证体系就会变得不安全。
- 要设置合理的 JWT 过期时间,避免过期时间过长导致安全风险,也不能过短影响用户体验。
四、动手实现 JWT 认证
安装 OpenResty
首先得安装 OpenResty,不同的操作系统安装方法不太一样。以 Ubuntu 为例,我们可以用下面的命令来安装:
# 导入 OpenResty 的 GPG 密钥
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
# 添加 OpenResty 的软件源
sudo add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
# 更新软件源
sudo apt-get update
# 安装 OpenResty
sudo apt-get install openresty
生成 JWT
我们用 Lua 脚本来生成 JWT。这里要用到 lua-resty-jwt 这个库,它可以方便地生成和验证 JWT。
-- 技术栈:Lua
-- 引入 lua-resty-jwt 库
local jwt = require "resty.jwt"
-- 定义 JWT 的密钥
local secret = "your_secret_key"
-- 定义 JWT 的载荷
local payload = {
sub = "user123",
name = "John Doe",
role = "admin"
}
-- 生成 JWT
local jwt_obj = jwt:sign(secret, {
header = { typ = "JWT", alg = "HS256" },
payload = payload
})
-- 打印生成的 JWT
ngx.say("Generated JWT: ", jwt_obj)
在这个示例中,我们首先引入了 lua-resty-jwt 库,然后定义了 JWT 的密钥和载荷。接着用 jwt:sign 方法生成 JWT,并把生成的 JWT 打印出来。
验证 JWT
下面我们来写一个 Lua 脚本来验证 JWT:
-- 技术栈:Lua
-- 引入 lua-resty-jwt 库
local jwt = require "resty.jwt"
-- 定义 JWT 的密钥
local secret = "your_secret_key"
-- 获取请求头中的 Authorization 字段
local auth_header = ngx.var.http_authorization
if not auth_header then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("Authorization header missing")
return
end
-- 提取 JWT
local _, _, token = string.find(auth_header, "Bearer%s+(.+)")
if not token then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("Invalid Authorization header")
return
end
-- 验证 JWT
local jwt_obj = jwt:verify(secret, token)
if not jwt_obj.verified then
ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.say("Invalid JWT")
return
end
-- JWT 验证通过
ngx.say("JWT verified successfully")
在这个示例中,我们首先获取请求头中的 Authorization 字段,然后提取出 JWT。接着用 jwt:verify 方法验证 JWT,如果验证通过,就输出 JWT verified successfully,否则返回 Invalid JWT。
配置 Nginx
我们要在 Nginx 的配置文件里配置 JWT 认证。假设我们有一个 API 接口 /api/user,只有通过 JWT 认证的用户才能访问。
http {
# 加载 lua-resty-jwt 库
lua_package_path "/path/to/lua-resty-jwt/?.lua;;";
server {
listen 80;
server_name example.com;
location /api/user {
# 执行 Lua 脚本进行 JWT 验证
access_by_lua_file /path/to/verify_jwt.lua;
# 处理请求
proxy_pass http://backend_server;
}
}
}
在这个配置文件中,我们首先加载了 lua-resty-jwt 库,然后在 /api/user 这个接口的配置里,用 access_by_lua_file 指令执行 verify_jwt.lua 脚本来验证 JWT。如果验证通过,就把请求转发到后端服务器。
五、总结
通过 OpenResty 实现 JWT 认证,我们可以构建一个安全的 API 访问控制体系。OpenResty 的高性能和灵活性让我们能轻松地实现各种认证逻辑,而 JWT 则提供了一种安全、便捷的身份验证方式。在实际应用中,我们要注意保管好 JWT 的密钥,设置合理的过期时间,确保认证体系的安全性。
评论