Update sso.js
This commit is contained in:
parent
4ab953a07b
commit
f3d6e6eb66
1 changed files with 96 additions and 84 deletions
180
sso.js
180
sso.js
|
|
@ -1,6 +1,3 @@
|
||||||
//simulate BMA SSO behavior Authenticator and reverse proxy
|
|
||||||
//cookie with token is the final product of SSO
|
|
||||||
|
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
const cookieParser = require('cookie-parser');
|
const cookieParser = require('cookie-parser');
|
||||||
const querystring = require("querystring");
|
const querystring = require("querystring");
|
||||||
|
|
@ -11,6 +8,8 @@ const cors = require('cors');
|
||||||
const jwt = require("jsonwebtoken");
|
const jwt = require("jsonwebtoken");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const axios = require("axios");
|
const axios = require("axios");
|
||||||
|
const CryptoJS = require("crypto-js");
|
||||||
|
const secretKey = "uuidSecretKey2025"; // ใช้เป็นคีย์สำหรับเข้ารหัส
|
||||||
|
|
||||||
const cookieName = process.env.SSO_COOKIE_NAME || "ssotoken";
|
const cookieName = process.env.SSO_COOKIE_NAME || "ssotoken";
|
||||||
const privateKey = fs.readFileSync(`./BMA`, "utf8");
|
const privateKey = fs.readFileSync(`./BMA`, "utf8");
|
||||||
|
|
@ -26,85 +25,107 @@ const urlKeycloakToken = `${process.env.KC_URL}/realms/${process.env.KC_REALMS}/
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
// Allow a specific origin and enable credentials
|
// ตั้งค่าการป้องกัน Origin
|
||||||
const corsOptions = {
|
const allowedOrigins = ['http://localhost:3002', 'https://hrmsbkk.case-collection.com']; // อนุญาตเฉพาะ domain ที่กำหนด //http://localhost:3002
|
||||||
origin: 'http://localhost:3002', // Replace with your Vue app's URL
|
|
||||||
methods: 'GET,POST,PUT,DELETE',
|
|
||||||
credentials: true, // Enable cookies or Authorization headers
|
|
||||||
};
|
|
||||||
|
|
||||||
app.use(cors(corsOptions));
|
app.use(cors({
|
||||||
|
origin: function (origin, callback) {
|
||||||
|
if (allowedOrigins.includes(origin)) {
|
||||||
|
callback(null, true); // อนุญาต
|
||||||
|
} else {
|
||||||
|
callback(new Error('Origin not allowed by CORS')); // ปฏิเสธ
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: ['GET', 'POST'], // จำกัดเฉพาะ method ที่อนุญาต
|
||||||
|
credentials: true,
|
||||||
|
}));
|
||||||
|
|
||||||
app.use(express.urlencoded({ extended: true }));
|
app.use(express.urlencoded({ extended: true }));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
app.use(cookieParser());
|
app.use(cookieParser());
|
||||||
|
|
||||||
|
app.get("/api/v1/sso", async (req, res) => {
|
||||||
|
res.status(200).send("HRMS API SSO");
|
||||||
|
});
|
||||||
|
|
||||||
app.post("/api/v1/sso/signin", async (req, res) => {
|
app.post("/api/v1/sso/signin", async (req, res) => {
|
||||||
|
const origin = req.headers.origin;
|
||||||
|
if (allowedOrigins.includes(origin)) {
|
||||||
|
try {
|
||||||
|
const login_user = req.body;
|
||||||
|
|
||||||
try {
|
const formdata = new URLSearchParams();
|
||||||
const login_user = req.body;
|
formdata.append("grant_type", "password");
|
||||||
|
formdata.append("client_id", process.env.VITE_CLIENTID_KEYCLOAK);
|
||||||
|
formdata.append("username", login_user.username);
|
||||||
|
formdata.append("password", login_user.password);
|
||||||
|
|
||||||
const formdata = new URLSearchParams();
|
await axios.post(urlKeycloakToken, formdata, {
|
||||||
formdata.append("grant_type", "password");
|
headers: {
|
||||||
formdata.append("client_id", process.env.VITE_CLIENTID_KEYCLOAK);
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
formdata.append("username", login_user.username);
|
},
|
||||||
formdata.append("password", login_user.password);
|
}).then(async () => {
|
||||||
|
const payload = { username: login_user.username };
|
||||||
|
let token = jwt.sign(payload, privateKey, signOptions);
|
||||||
|
|
||||||
await axios.post(urlKeycloakToken, formdata, {
|
res.cookie(cookieName, token, {
|
||||||
headers: {
|
maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
path: "/",
|
||||||
},
|
httpOnly: true,
|
||||||
}).then(() => {
|
});
|
||||||
const payload = { username: login_user.username };
|
|
||||||
let token = jwt.sign(payload, privateKey, signOptions);
|
|
||||||
|
|
||||||
res.cookie(cookieName, token, {
|
const uid = await CryptoJS.AES.encrypt(login_user.username, secretKey).toString();
|
||||||
maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond
|
res.status(200).send({ uid });
|
||||||
path: "/",
|
|
||||||
httpOnly: true,
|
}).catch((err) => {
|
||||||
|
if (err.status) {
|
||||||
|
res.status(401).send("Incorrect user or password");
|
||||||
|
} else
|
||||||
|
res.status(err.status).send(error);
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
res.sendStatus(200);
|
res.status(500).send(error);
|
||||||
}).catch((err) => {
|
}
|
||||||
if (err.status) {
|
} else {
|
||||||
res.status(401).send("Incorrect user or password");
|
res.status(403).json({ error: 'Forbidden: Origin not allowed' });
|
||||||
} else
|
|
||||||
res.status(err.status).send(error);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).send(error);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.post("/api/v1/sso/kcauth", async (req, res) => {
|
app.post("/api/v1/sso/kcauth", async (req, res) => {
|
||||||
try {
|
const origin = req.headers.origin;
|
||||||
// kcauth
|
if (allowedOrigins.includes(origin)) {
|
||||||
const useBMA = Boolean(process.env.USE_BMA) || false;
|
try {
|
||||||
const publicKeyLanding = fs.readFileSync(`./BMA.pub.pem`, "utf8");
|
// kcauth
|
||||||
const clientSecret = process.env.KC_CLIENT_SECRET;
|
// const useBMA = Boolean(process.env.USE_BMA) || false;
|
||||||
const clientId = process.env.KC_CLIENT_ID;
|
// const publicKeyLanding = fs.readFileSync(`./BMA.pub.pem`, "utf8");
|
||||||
|
const clientSecret = process.env.KC_CLIENT_SECRET;
|
||||||
|
const clientId = process.env.KC_CLIENT_ID;
|
||||||
|
|
||||||
const cookies = req.cookies;
|
// const cookies = req.cookies;
|
||||||
const tokenSSO = cookies[cookieName];
|
// const tokenSSO = cookies[cookieName];
|
||||||
|
//if (tokenSSO) {
|
||||||
|
// let decodedToken = "";
|
||||||
|
// if (useBMA) {
|
||||||
|
// decodedToken = jwt.decode(tokenSSO);
|
||||||
|
// } else {
|
||||||
|
// decodedToken = jwt.verify(tokenSSO, publicKeyLanding);
|
||||||
|
// }
|
||||||
|
// let d = JSON.parse(JSON.stringify(decodedToken));
|
||||||
|
// console.log("==== username from cookies ====", d);
|
||||||
|
// username = d.username;
|
||||||
|
// }
|
||||||
|
|
||||||
if (!tokenSSO) {
|
// send uid from client
|
||||||
res.status(401).send("Unauthorized");
|
const uid = req.body.uid;
|
||||||
return;
|
if (!uid) {
|
||||||
}
|
res.status(401).send("Unauthorized");
|
||||||
|
return;
|
||||||
const oldssotoken = cookies['oldssotoken'];
|
|
||||||
|
|
||||||
if (tokenSSO !== oldssotoken) {
|
|
||||||
|
|
||||||
let decodedToken = "";
|
|
||||||
if (useBMA) {
|
|
||||||
decodedToken = jwt.decode(tokenSSO);
|
|
||||||
} else {
|
|
||||||
decodedToken = jwt.verify(tokenSSO, publicKeyLanding);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let d = JSON.parse(JSON.stringify(decodedToken));
|
let username = "";
|
||||||
// console.log("==== username from cookies ====", d);
|
const bytes = CryptoJS.AES.decrypt(uid, secretKey);
|
||||||
const username = d.username;
|
const decrypted = bytes.toString(CryptoJS.enc.Utf8);
|
||||||
|
username = decrypted;
|
||||||
|
|
||||||
// create body for admin token
|
// create body for admin token
|
||||||
let body = {
|
let body = {
|
||||||
|
|
@ -121,6 +142,7 @@ app.post("/api/v1/sso/kcauth", async (req, res) => {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// console.log("==== admin token ====");
|
// console.log("==== admin token ====");
|
||||||
const adminToken = response.data.access_token;
|
const adminToken = response.data.access_token;
|
||||||
// console.log(adminToken);
|
// console.log(adminToken);
|
||||||
|
|
@ -137,10 +159,8 @@ app.post("/api/v1/sso/kcauth", async (req, res) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const postData2 = querystring.stringify(body2);
|
const postData2 = querystring.stringify(body2);
|
||||||
// console.log("==== postData2 ====");
|
|
||||||
// console.log(body2);
|
|
||||||
|
|
||||||
// get admin token
|
// get token for user
|
||||||
const tokenResponse = await axios.post(urlKeycloakToken, postData2, {
|
const tokenResponse = await axios.post(urlKeycloakToken, postData2, {
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
|
@ -150,29 +170,21 @@ app.post("/api/v1/sso/kcauth", async (req, res) => {
|
||||||
// console.log("==== user token ====");
|
// console.log("==== user token ====");
|
||||||
// console.log(tokenResponse.data);
|
// console.log(tokenResponse.data);
|
||||||
// await postLog('เข้าสู่ระบบ', tokenResponse.data.access_token);
|
// await postLog('เข้าสู่ระบบ', tokenResponse.data.access_token);
|
||||||
res.cookie('oldssotoken', tokenSSO, {
|
// res.cookie('oldssotoken', tokenSSO, {
|
||||||
maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond
|
// maxAge: 1000 * 60 * 60 * 24, // กำหนด timeout หน่วยเป็น millisecond
|
||||||
path: "/",
|
// path: "/",
|
||||||
httpOnly: true,
|
// httpOnly: true,
|
||||||
});
|
// });
|
||||||
|
|
||||||
res.status(200).send(tokenResponse.data);
|
res.status(200).send(tokenResponse.data);
|
||||||
} else {
|
|
||||||
res.status(200).send({ isLogin: true });
|
} catch (error) {
|
||||||
|
res.status(500).send(error);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
} catch (error) {
|
res.status(403).json({ error: 'Forbidden: Origin not allowed' });
|
||||||
// console.log("error===>", error);
|
|
||||||
|
|
||||||
res.status(500).send(error);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// app.use(express.static(path.join(__dirname, "public-sso")));
|
|
||||||
|
|
||||||
// app.get("/", (_req, res) => {
|
|
||||||
// res.sendFile(`${process.cwd()}/sso.js`);
|
|
||||||
// });
|
|
||||||
|
|
||||||
console.log("Start BMA SSO Simulator at port " + port);
|
console.log("Start BMA SSO Simulator at port " + port);
|
||||||
app.listen(port);
|
app.listen(port);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue