惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
Microsoft Security Blog
Microsoft Security Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园_首页
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
G
GRAHAM CLULEY
H
Hackread – Cybersecurity News, Data Breaches, AI and More
阮一峰的网络日志
阮一峰的网络日志
L
Lohrmann on Cybersecurity
S
Security @ Cisco Blogs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Security Affairs
The Cloudflare Blog
A
About on SuperTechFans
Google DeepMind News
Google DeepMind News
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Spread Privacy
Spread Privacy
Y
Y Combinator Blog
V2EX - 技术
V2EX - 技术
罗磊的独立博客
F
Full Disclosure
Jina AI
Jina AI
S
Schneier on Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
CXSECURITY Database RSS Feed - CXSecurity.com
Webroot Blog
Webroot Blog
雷峰网
雷峰网
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recorded Future
Recorded Future
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 三生石上(FineUI控件)
K
Kaspersky official blog
V
Visual Studio Blog
Vercel News
Vercel News
Cyberwarzone
Cyberwarzone
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
Tor Project blog
Cloudbric
Cloudbric
Hacker News - Newest:
Hacker News - Newest: "LLM"
爱范儿
爱范儿
L
LINUX DO - 最新话题
GbyAI
GbyAI
Attack and Defense Labs
Attack and Defense Labs
H
Heimdal Security Blog
Recent Announcements
Recent Announcements
L
LINUX DO - 热门话题
L
LangChain Blog
Simon Willison's Weblog
Simon Willison's Weblog

侯锐的思考与分享

大数据技术的演进:从 Hive、GFS 到 Raft 如何进行站点网络优化 使用Elasticsearch分析腾讯云EO日志 XXL-JOB的部署、搭建与使用 使用APISIX解析jwt并获取payload信息 《推荐系统实践》 《上瘾:让用户养成使用习惯的四大产品逻辑》 Kotlin与Java对照手册 ComfyUI的操作与使用 ComfyUI简介 利用whisper为视频自动生成字幕 ffmpeg笔记 如何参与Apache顶级开源项目 使用frp实现内网ssh穿透 安装并使用zsh APISIX的使用 自己动手实现一个可以运行在JVM上的编程语言 使用ANTLR4格式化JSON ANTLR4从入门到实践 ShardingSphere-JDBC介绍 Maven详细介绍
使用NGINX的auth_request进行统一jwt鉴权
Raymond · 2025-07-24 · via 侯锐的思考与分享

NGINX的auth_request模块提供了一种统一的认证机制,可以在NGINX层面进行JWT鉴权,而不需要在每个后端服务中重复实现认证逻辑。

首先我们定义一下nginx的配置,它的配置如下

flat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server {
listen 8965;

# 鉴权接口,仅供 Nginx 内部 auth_request 使用
location = /auth {
internal; # 该接口只能被 Nginx 内部请求,防止外部访问
# 转发到实际的认证服务
proxy_pass http://localhost:5001/api/auth/verify;
# 不转发请求体,提升效率
proxy_pass_request_body off;
# 防止后端因 Content-Length 不确定而报错
proxy_set_header Content-Length "";
# 将客户端传来的 Authorization 头(JWT Token)传给认证服务
proxy_set_header Authorization $http_authorization;
# 传入原始请求路径,供认证服务判断路径是否需要鉴权
proxy_set_header X-Original-URI $request_uri;
}

# 所有 / 路径下的请求都进行认证
location / {
# 认证请求会先调用上面的 /auth 接口
auth_request /auth;
# 如果认证失败(如返回 401),跳转到自定义处理逻辑
error_page 401 = @unauthorized;
# 从 /auth 的响应头中提取用户信息
auth_request_set $user_id $upstream_http_x_user_id;
# 把用户信息注入到请求头中,转发给后端业务服务
proxy_set_header X-User-ID $user_id;
# 转发到后端服务
proxy_pass http://localhost:5001;
}

# 自定义未授权响应(认证失败时返回)
location @unauthorized {
# 返回 401 状态码 + 文本内容
return 401 "Unauthorized";
}
}

有了这个nginx的配置之后,我们就可以实现鉴权的逻辑了,具体逻辑如下

flat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import jwt
from flask import Flask, request, make_response, jsonify
from jwt import InvalidTokenError

app = Flask(__name__)

SECRET_KEY = "a-string-secret-at-least-256-bits-long"


PUBLIC_PATHS = [
"/api/public/hello",
"/api/login",
"/api/register"
]


@app.route("/api/auth/verify", methods=["GET"])
def verify_token():
original_uri = request.headers.get("X-Original-URI", "")

if original_uri in PUBLIC_PATHS:
return "", 200


auth_header = request.headers.get("Authorization")
if not auth_header or not auth_header.startswith("Bearer "):
return "Missing or invalid Authorization header", 401


token = auth_header.split(" ", 1)[1]
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
response = make_response("", 200)
response.headers["X-User-ID"] = str(payload.get("user_id", ""))
return response
except InvalidTokenError:
return "Invalid token", 401


@app.route("/api/hello")
def hello():
return jsonify({"message": "hello from auth", "user_id": request.headers.get("X-User-ID")})


@app.route("/api/public/hello")
def ping():
return {"msg": "hello without auth"}


if __name__ == "__main__":
app.run(host="0.0.0.0", port=5001)

启动nginx和如上python服务,之后我们使用如下payload和header以及密钥生成token

payload

{
    "alg": "HS256",
    "typ": "JWT"
}

header

{
    "user_id": 656670838050885
}

密钥

a-string-secret-at-least-256-bits-long

生成得到token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo2NTY2NzA4MzgwNTA4ODV9.caQ6cp-BA-OMxXu4zTUjV0OiZo1iygvdi7GPQNjNVHM

之后我们就可以使用token进行测试了,具体测试结果如下

~ AUTH_HEADER="Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjo2NTY2NzA4MzgwNTA4ODV9.caQ6cp-BA-OMxXu4zTUjV0OiZo1iygvdi7GPQNjNVHM"

~ curl -H "$AUTH_HEADER" http://localhost:8965/api/hello
{"message":"hello from auth","user_id":"656670838050885"}

~ curl -H "$AUTH_HEADER" http://localhost:8965/api/public/hello
{"msg":"hello without auth"}

~ curl -H "$AUTH_HEADER" http://localhost:8965/api/login
<!doctype html>
<html lang=en>
<title>404 Not Found</title>
<h1>Not Found</h1>
<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>

~ curl http://localhost:8965/api/public/hello
{"msg":"hello without auth"}

~ curl http://localhost:8965/api/hello
Unauthorized%

如上我们正确设置了Authorization之后就可以正常访问需要鉴权的接口了,但是去掉了Authorization之后需要鉴权的接口就会返回Unauthorized。此外还可以看到,不需要鉴权的接口,即使不添加鉴权配置也是可以正常访问的。

本文链接: https://www.nosuchfield.com/2025/07/24/Using-NGINX-auth_request-for-unified-JWT-authentication/