Traefik 미들웨어 - 정방향 인증
맞춤 인증
사용자 지정 인증은 관리를 외부 서버에 위임합니다.
사용자 지정 인증을 관리하기 위해 ForwardAuth Middleware을 사용합니다.
이 예에서는 JWT 토큰이 포함된 쿠키로 인증을 유지하는 NodeJS Express 서버를 만듭니다.
미들웨어를 통과하는 모든 요청에 대해 JWT 토큰을 확인합니다.
존재하지 않거나 만료된 경우 상태 코드
401
와 함께 클라이언트에 로그인 양식을 보냅니다.이전 비밀
basic-auth-users-secret
을 사용하여 계정을 관리합니다.이것은 일종의 구현이지만 많은 인증 워크플로를 상상할 수 있습니다.
NodeJS 서버를 고정 표시하는 방법은 설명하지 않지만 많은 자습서를 찾을 수 있습니다.
서버 구현
다음 환경 변수를 정의해야 합니다.
COOKIE
: JWT를 유지할 쿠키의 이름SECRET
: JWT를 관리하는 JWT 암호USERS_PATH
: 사용자 파일의 경로VALIDITY
: 인증 유효 기간(초)이 예제에서는 요청 본문이 서버로 전달되지 않기 때문에 양식 값이 HTTP 헤더로 전송됩니다.
const express = require('express');
const router = express.Router();
const jwt = require('jsonwebtoken');
const atob = require('atob');
const htpasswd = require('htpasswd-js');
const cookie = process.env.COOKIE;
const key = process.env.SECRET;
const usersPath = process.env.USERS_PATH;
const validity = parseInt(process.env.VALIDITY);//in seconds
router.all('/', function (req, res, next) {
let forwarded = {
method: req.header("X-Forwarded-Method"),
protocol: req.header("X-Forwarded-Proto"),
host: req.header("X-Forwarded-Host"),
uri: req.header("X-Forwarded-Uri"),
ip: req.header("X-Forwarded-For"),
};
let url = `${forwarded.protocol}://${forwarded.host}${forwarded.uri}`;
let roles = req.query.roles;
try {
if (cookie in req.cookies) {
// Check JWT token
let decoded = jwt.verify(req.cookies[cookie], key);
res.sendStatus(200);
return;
}
else if (forwarded.method.toUpperCase() == "POST") {
// Check login/password
let form = req.header("Form-Content");
form = atob(form);
let [login, password] = form.split(":");
let loggedIn = htpasswd.authenticate({
username: login,
password,
file: usersPath
});
if (!loggedIn) throw new Error("Not logged in");
console.log(`Logged in ${login}. Redirect to ${url}`);
// Create JWT token
let val = (req.query.validity || validity) * 1000;
let expire = val + Date.now();
let token = jwt.sign({ user: login, exp: Math.floor(expire / 1000) }, key);
res.cookie(cookie, token, {
secure: true,
httpOnly: true,
expire: new Date(expire)
});
res.status(302);
res.header("Location", url);
// redirect to initial url
res.render('redirect', { title: 'Redirect', url });
return;
}
}
catch (er) {
console.error(er);
res.clearCookie(cookie);
}
res.status(401);
res.render('index', { title: 'Login', url , js: `function sendForm(e) {
var form = e.currentTarget;
var xhr = new XMLHttpRequest();
var formData = new FormData(form);
xhr.addEventListener('load', function(event) {
window.location.reload();
});
xhr.addEventListener('error', function(event) {
alert('Oups! Something went wrong.');
});
xhr.open('POST', '');
xhr.setRequestHeader('Form-Content', btoa(form.login.value+':'+form.password.value));
xhr.send(formData);
e.preventDefault();
e.stopPropagation();
return false;
}`});
});
module.exports = router;
다음은
index
보기입니다.extends layout
block content
h1= "Login"
form(method="post", onsubmit="return sendForm(event);")
input(name="login")
input(name="password", type="password")
input(name="redirect", type="hidden", value= url)
button= "Login"
script= js
다음은
redirect
보기입니다.extends layout
block content
h1= "Redirection en cours"
script= `window.location = "${url}";`
인증 미들웨어 배포
먼저 필요한 환경 변수를 포함하는 비밀을 정의합니다.
apiVersion: v1
kind: Secret
metadata:
name: custom-auth-secret
stringData:
# The cookie name
COOKIE: my-cookie-name
# The JWT
SECRET: The jwt secret key
# The JWT and cookie validity in seconds
VALIDITY: "1800"
서버 배포 및 서비스를 정의해 보겠습니다.
kind: Deployment
apiVersion: apps/v1
metadata:
name: custom-auth
labels:
k8s-app: custom-auth
spec:
replicas: 1
selector:
matchLabels:
k8s-app: custom-auth
template:
metadata:
name: custom-auth
labels:
k8s-app: custom-auth
spec:
containers:
- name: custom-auth
image: custom-auth-server:latest
env:
- name: USERS_PATH
value: /auth/users
envFrom:
- secretRef:
name: custom-auth-secret
volumeMounts:
- name: users
mountPath: "/auth"
readOnly: true
volumes:
- name: users
secret:
secretName: basic-auth-users-secret
---
kind: Service
apiVersion: v1
metadata:
name: custom-auth
labels:
k8s-app: custom-auth
spec:
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
selector:
k8s-app: custom-auth
이제 서버의 동일한 네임스페이스에서 Traefik ForwardAuth 미들웨어를 정의합니다.
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: custom-auth
spec:
forwardAuth:
address: http://auth.traefik:8080
이제 Traefik 라우터에서 사용할 수 있습니다.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: test-custom-auth
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`test-custom-auth.lenra.io`)
middlewares:
- name: test-custom-auth
# Define the middleware namespace if you use is it another one
# namespace: my-namespace
services:
- kind: Service
name: my-service
port: 8080
더 나아가
이 인증 시스템을 개선하기 위해 많은 것을 상상할 수 있습니다.
Reference
이 문제에 관하여(Traefik 미들웨어 - 정방향 인증), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/lenra/traefik-middleware-forward-authentication-1nc1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)