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

问题描述

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

解决方法

已解决

我可以按照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,next) => {    
    next(createError(404,'Not found'));
});

// Error Handler
app.use((err,req,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}`);
});

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...