认证与授权
使用 Ring 中间件实现基于令牌的认证和基于角色的授权,保护您的 Clojure 后端。
认证与授权 是 CoddyKit 上的免费 Clojure Functional Programming & JVM Backend Development 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Clojure Functional Programming & JVM Backend Development 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Clojure Functional Programming & JVM Backend Development 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
AuthN vs AuthZ
Two distinct concerns:
- Authentication (AuthN): who are you?
- Authorization (AuthZ): what are you allowed to do?
You must verify identity before checking permissions.
Hashing Passwords
Never store plain passwords. Use a slow, salted hash like bcrypt via the buddy library.
(require '[buddy.hashers :as hashers])
(def stored (hashers/derive "secret123"))
(hashers/check "secret123" stored) ; => trueWhat Is a JWT?
A JSON Web Token is a signed, self-contained token holding claims (user id, roles, expiry). The server can verify it without a database lookup.
Issuing a Token
On successful login, sign a token containing the user's claims with a secret key.
(require '[buddy.sign.jwt :as jwt])
(defn make-token [user]
(jwt/sign {:user-id (:id user) :role (:role user)}
secret-key))Verifying a Token
On each request, read the token from the Authorization header and verify the signature. An invalid or expired token throws.
(defn verify [token]
(jwt/unsign token secret-key))Authentication Middleware
Wrap handlers so the verified identity is attached to the request, or a 401 is returned.
(defn wrap-auth [handler]
(fn [request]
(if-let [token (bearer-token request)]
(handler (assoc request :identity (verify token)))
{:status 401 :body "Unauthorized"})))Role-Based Authorization
Once identity is known, check roles before allowing an action.
(defn require-role [role handler]
(fn [request]
(if (= role (get-in request [:identity :role]))
(handler request)
{:status 403 :body "Forbidden"})))401 vs 403
Use the right status:
- 401 Unauthorized: not authenticated (no/invalid token)
- 403 Forbidden: authenticated but lacks permission
Protecting Routes
Combine middleware with Compojure to guard specific endpoints while leaving public ones open.
(defroutes app
(GET "/health" [] ok)
(-> (GET "/admin" [] admin-page)
(#(require-role :admin %))
wrap-auth))Token Expiry & Refresh
Set short expiry on access tokens to limit damage if leaked, and issue long-lived refresh tokens to get new ones without re-login.
(jwt/sign {:user-id 1 :exp (+ (now) 900)} secret-key)Security Best Practices
Key rules:
- Always serve auth over HTTPS
- Store secrets in environment variables, not code
- Hash passwords with bcrypt/argon2
- Keep access tokens short-lived
Quick Check
Test your security knowledge.
Recap
You learned to secure a Clojure backend.
- Hash passwords with bcrypt
- Issue and verify JWTs for stateless auth
- Use middleware for AuthN and role checks for AuthZ
- Return 401 vs 403 correctly
常见问题解答
「认证与授权」课时是免费的吗?
是的 — 「认证与授权」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Clojure Functional Programming & JVM Backend Development 课程的其余内容,请升级到 CoddyKit PRO。 Clojure Functional Programming & JVM Backend Development 课程共包含 4 节课。
「认证与授权」这节课中我会学到什么?
使用 Ring 中间件实现基于令牌的认证和基于角色的授权,保护您的 Clojure 后端。 你通过在浏览器中直接运行的动手代码来练习 Clojure Functional Programming & JVM Backend Development,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Clojure Functional Programming & JVM Backend Development 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Clojure Functional Programming & JVM Backend Development 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「认证与授权」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Clojure Functional Programming & JVM Backend Development 课中编写并运行代码吗?
能。每节 Clojure Functional Programming & JVM Backend Development 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。