调用rest api时,keycloak注销不会使令牌无效

时间:2020-08-19 17:48:39

标签: jwt keycloak logout keycloak-rest-api keycloak-nodejs-connect

我有一个使用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"    
}

1 个答案:

答案 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}`);
});