Keycloak 的架构与应用
Table of Contents
Keycloak 的架构与应用
一、什么是 Keycloak?
Keycloak 是一个开源的身份与访问管理(IAM)解决方案,它帮我们搞定登录、单点登录(SSO)、注册、社交登录、MFA、多租户等等——简单说,就是把“怎么登录”的锅交给它,我们专注于写业务代码就行了。
你可以把它想象成“统一认证中心”,你应用里所有关于“用户是谁”“有没有权限”的问题,都可以丢给它来处理。
Keycloak 支持哪些协议?
- OAuth 2.0:现代认证的主流协议,像 GitHub 登录那套就是它。
- OIDC(OpenID Connect):在 OAuth 2.0 上封装一层,用于获取“用户是谁”的信息。
- SAML 2.0:主要是企业、老系统在用。
二、Keycloak 架构一图流
+-------------+ +--------------------+ +-------------+
| 浏览器 | <---> | 前端 Vue 应用 | <---> | |
+-------------+ +--------------------+ | |
| Keycloak |
+-------------+ +--------------------+ | |
| Python | <---> | 后端 FastAPI | <---> | |
+-------------+ +--------------------+ +-------------+
- 前端跳转 Keycloak 登录;
- 登录成功后,拿到 token;
- 后端用这个 token 验证身份、获取用户信息。
三、安装 Keycloak(容器版)
用 Docker 安装最简单,以下是快速上手命令:
docker run -d \
--name keycloak \
-p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:24.0.1 \
start-dev
然后访问:http://localhost:8080
使用 admin/admin
登录 Keycloak 管理控制台。
四、配置 Realm、Client 和用户
- 登录控制台,创建一个 Realm(可以理解成一个“用户空间”);
- 在 Realm 下创建一个 Client(比如叫
my-app
);- 类型:OpenID Connect
- Client ID:
my-app
- Root URL:
http://localhost:5173
- Valid Redirect URIs:
http://localhost:5173/*
- 创建用户并设置密码;
- 给 Client 启用 标准流(Authorization Code Flow);
- 打开
Credentials
记下Client Secret
。
五、后端(Python FastAPI 示例)
安装依赖:
pip install fastapi uvicorn python-dotenv httpx
创建 .env
文件:
KEYCLOAK_CLIENT_ID=my-app
KEYCLOAK_CLIENT_SECRET=你的密钥
KEYCLOAK_REALM=your-realm
KEYCLOAK_URL=http://localhost:8080
REDIRECT_URI=http://localhost:8000/auth/callback
创建 main.py
:
import os
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import RedirectResponse, JSONResponse
from dotenv import load_dotenv
import httpx
load_dotenv()
app = FastAPI()
CLIENT_ID = os.getenv("KEYCLOAK_CLIENT_ID")
CLIENT_SECRET = os.getenv("KEYCLOAK_CLIENT_SECRET")
REALM = os.getenv("KEYCLOAK_REALM")
KEYCLOAK_URL = os.getenv("KEYCLOAK_URL")
REDIRECT_URI = os.getenv("REDIRECT_URI")
@app.get("/auth/login")
def login():
return RedirectResponse(
f"{KEYCLOAK_URL}/realms/{REALM}/protocol/openid-connect/auth"
f"?client_id={CLIENT_ID}&response_type=code&redirect_uri={REDIRECT_URI}"
)
@app.get("/auth/callback")
async def callback(code: str):
async with httpx.AsyncClient() as client:
token_resp = await client.post(
f"{KEYCLOAK_URL}/realms/{REALM}/protocol/openid-connect/token",
data={
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"code": code,
"grant_type": "authorization_code",
"redirect_uri": REDIRECT_URI,
},
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
token_json = token_resp.json()
access_token = token_json.get("access_token")
return RedirectResponse(f"http://localhost:5173?access_token={access_token}")
@app.get("/api/me")
async def get_user(request: Request):
auth = request.headers.get("Authorization")
if not auth:
raise HTTPException(status_code=401, detail="Missing token")
token = auth.split(" ")[1]
async with httpx.AsyncClient() as client:
userinfo_resp = await client.get(
f"{KEYCLOAK_URL}/realms/{REALM}/protocol/openid-connect/userinfo",
headers={"Authorization": f"Bearer {token}"}
)
return userinfo_resp.json()
六、前端(Vue.js)
安装 Vue 项目
npm init vue@latest
cd your-project
npm install axios
修改 App.vue
<script setup>
import { ref, onMounted } from 'vue'
import axios from 'axios'
const user = ref(null)
const login = () => {
window.location.href = 'http://localhost:8000/auth/login'
}
const logout = () => {
localStorage.removeItem('token')
user.value = null
}
const fetchUser = async () => {
const token = localStorage.getItem('token')
if (!token) return
try {
const res = await axios.get('http://localhost:8000/api/me', {
headers: {
Authorization: `Bearer ${token}`,
},
})
user.value = res.data
} catch {
logout()
}
}
onMounted(() => {
const params = new URLSearchParams(window.location.search)
const token = params.get('access_token')
if (token) {
localStorage.setItem('token', token)
window.history.replaceState({}, '', '/')
}
fetchUser()
})
</script>
<template>
<div>
<h1>Keycloak 登录示例</h1>
<div v-if="user">
<p>你好,{{ user.name || user.preferred_username }}!</p>
<button @click="logout">退出登录</button>
</div>
<div v-else>
<button @click="login">使用 Keycloak 登录</button>
</div>
</div>
</template>
七、总结
Keycloak 就像你项目的“门神”,它守住大门,确保“什么人能进”“进来了是谁”。通过标准协议(OAuth、OIDC)对接,你不需要重复造轮子,就能让你的系统拥有现代化的用户身份管理功能。
本文通过一个 Vue + FastAPI 的小例子,带你跑通了 Keycloak 的一个最基本应用场景。后续你可以探索更多特性,比如:
- 社交登录(Google、GitHub 一键接入)
- 多因素认证(MFA)
- 自定义用户界面
- 与企业 AD、LDAP 集成
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。
Comments |0|
Category: cloud