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.)