我有一个使用Keycloak作为身份验证服务的React应用。另外我还有一个Nodejs rest api,其端点由keycloak保护,因此React应用在需要调用api时发送JWT。在Keycloak管理控制台中,我创建了1个具有用户和角色的公共客户端。
一切正常,但是唯一的问题是当我通过管理控制台注销时,或者 在到期时间之前从我的React应用程序中,我仍然可以使用这些令牌调用我的应用程序。
为什么我的后端应用程序无法通过服务器验证令牌?
我的节点应用程序使用keycloak-node-connect适配器,而我的keycloak.json是:
{
"client-id": "my-public-client",
"bearer-only": true,
"auth-server-url": "http://localhost:8180/auth",
"realm": "my-realm"
}
答案 0 :(得分:0)
我可以按照Keycloak: Access token validation end point
中的建议解决我的问题keycloak.config.js
var session = require('express-session');
var Keycloak = require('keycloak-connect');
var request = require('request');
const createError = require('http-errors');
let _keycloak;
var memoryStore = new session.MemoryStore();
function initKeycloak() {
if (_keycloak) {
console.log("Trying to init Keycloak again!");
return _keycloak;
}
else {
console.log("Initializing Keycloak...");
_keycloak = new Keycloak({ store: memoryStore });
return _keycloak;
}
}
function getKeycloak() {
if (!_keycloak) {
console.error('Keycloak has not been initialized. Please called init first.');
}
return _keycloak;
}
async function validateTokenKeycloak(req, res, next) {
if (req.kauth && req.kauth.grant) {
console.log('--- Verify token ---');
try {
var result = await _keycloak.grantManager.userInfo(req.kauth.grant.access_token);
//var result = await _keycloak.grantManager.validateAccessToken(req.kauth.grant.access_token);
if(!result) {
console.log(`result:`, result);
throw Error('Invalid Token');
}
} catch (error) {
console.log(`Error: ${error.message}`);
return next(createError.Unauthorized());
}
}
next();
}
module.exports = {
memoryStore,
initKeycloak,
getKeycloak,
validateTokenKeycloak
};
app.js
const express = require('express');
const createError = require('http-errors');
const dotenv = require('dotenv').config();
const session = require('express-session');
const keycloakConfig = require('./config/keycloak.config');
const app = express();
// Keycloak
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: true,
store: keycloakConfig.memoryStore
}));
const keycloak = keycloakConfig.initKeycloak();
app.use(keycloak.middleware());
app.use(keycloakConfig.validateTokenKeycloak);
app.use("/health", require('./routes/health.route'));
// 404 handler and pass to error handler
app.use((req, res, next) => {
next(createError(404, 'Not found'));
});
// Error Handler
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.send({
error : {
status : err.status || 500,
message : err.message
}
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server starter on port ${PORT}`);
});