路由如下所示,其中verifyToken是一个中间件.

router.get('/v1/endpoint', verifytoken, apis.getData);

为了保护这条路由,我们通常使用keycloak.protect();但我想使用verifyToken,这是一个中间件,无论该路由是否受到保护,它总是转到apis.getDatat.但是中间件函数将根据用户是否经过身份验证附加一个字符串.

router.get('/v1/endpoint', keycloak.protect(), apis.getData);

这段代码应该运行并保护路由,并且基于它是否被授权,我想添加验证的字符串,apis.getData将使用该字符串来发送正确的数据量.

const keycloak = require('../../keycloak').getKeycloak();

/**
 * @param {Object} request - request object with authorization header.
 * @param {Object} response - response object.
 * @param {Object} next - calls the next function with user payload.
 */
module.exports = function(request, response, next) {
    // authorization token.
    const token = request.headers.authorization;

    // if token is not sent the authorization fails.
    if (!token) {
        return response.status(401).send('Access Denied, missing authorization token!');
    }

    // check if the token is valid or not.
    try {
        const verified = {};
        if (keycloak.protect()) {
            verified.verified = 'verified';
        }
        console.log('Token is verified', verified);
        response.locals.user = verified;
        next();
    } catch (err) {
        console.log('Token invalid!!!');
        response.locals.user = 'unknown';
        next();
    }
};

用于配置密钥罩的代码

const session = require('express-session');
const Keycloak = require('keycloak-connect');
const keycloakConfig = require('./keycloak.json');

let _keycloak;

function initKeycloak() {
    if (_keycloak) {
        console.warn('Trying to init Keycloak again!');
        return _keycloak;
    }

    console.log('Initializing Keycloak...');
    const memoryStore = new session.MemoryStore();
    _keycloak = new Keycloak({ store: memoryStore }, keycloakConfig);
    return _keycloak;
}

function getKeycloak() {
    if (!_keycloak) {
        console.error('Keycloak has not been initialized. Please called init first.');
    }
    return _keycloak;
}

module.exports = {
    initKeycloak,
    getKeycloak,
};

推荐答案

我将演示如何使用自定义令牌验证 我的演示以keycloak-nodejs-connect人中的example人为基础

我只是修改了代码.这不是完整的示例代码.

View/index.html中的用户界面

<div class="nav">
    <ul>
        <li><a href="/login">Login</a></li>
        <li><a href="/protected/resource">Protected Resource</a></li>
        <li><a href="/verify">Token Verify</a></li>
        <li><a href="/logout">Logout</a></li>
    </ul>
</div>

Index.js中的JavaScript

function my_token_verify(token, req, res) {
  // no token, it makes access denied
  if (!token || !token.token) {
    return false;
  }
  console.log(token.token);
  console.log(token.header);
  console.log(token.content);
  console.log(token.signature);
  console.log(token.clientId);
  // whatever your own logic for verify token
  if (token.header.alg == 'RS256' && token.header.typ == 'JWT')
    return true;
  return false;
}

app.get('/verify', keycloak.protect(my_token_verify), function (req, res) {
  res.render('index', {
    result: JSON.stringify(JSON.parse(req.session['keycloak-token']), null, 4),
    event: 'verify token: true'
  })
})

浏览器的结果, 如果从my_Token_Verify()返回TRUE,则将显示此屏幕.

enter image description here

如果my_Token_Verify()返回FALSE,则将显示访问被拒绝.

enter image description here VS code debug configuration

{
    "version": "0.2.0",
    "configurations": [
        {
            "command": "npm start",
            "name": "Run npm start",
            "request": "launch",
            "type": "node-terminal",
            "resolveSourceMapLocations": [
                "${workspaceFolder}/**",
                "!**/node_modules/**"
            ]
        }
    ]
}

VS代码中的终端输出

Debugger attached.
Example app listening at http://:::3000
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJGSjg2R2NGM2pUYk5MT2NvNE52WmtVQ0lVbWZZQ3FvcXRPUWVNZmJoTmxFIn0.eyJleHAiOjE2NjMwOTcxMjksImlhdCI6MTY2MzA2NDc0MSwiYXV0aF90aW1lIjoxNjYzMDYxMTI5LCJqdGkiOiIzNWM0MWIyZi0xMDc3LTQ1ZjMtYmFjOC04N2YxYWUyMDY1MGIiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvYXV0aC9yZWFsbXMvbm9kZWpzLWV4YW1wbGUiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiOTlhYTBlZDMtMjljMS00NTdhLTg2OGYtMjVjZTlhOTMxZDAzIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoibm9kZWpzLWNvbm5lY3QiLCJzZXNzaW9uX3N0YXRlIjoiNGZmNGFjNGItZTkzOS00YWYzLWJhNDMtZjU4NjlmYTM4NmNkIiwiYWNyIjoiMCIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1ub2RlanMtZXhhbXBsZSJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIGVtYWlsIHByb2ZpbGUiLCJzaWQiOiI0ZmY0YWM0Yi1lOTM5LTRhZjMtYmE0My1mNTg2OWZhMzg2Y2QiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluLXVzZXIifQ.F-u7QIuku81f5e6EAPddKllE_8xGw7zF0GrlPsqUYOAdIlwLvIrCjdLh2l1PmcpE4J6wWS9jLk8swA5hIySy2Z-X9k8OzxqY4nWXSbeOmIKY-fXqRZmV7_nNuo4b3veQv3JPfbpUhP96yFun4jDeTbbJFycvr_u0wg4KZoqrXhc
{
  alg: 'RS256',
  typ: 'JWT',
  kid: 'FJ86GcF3jTbNLOco4NvZkUCIUmfYCqoqtOQeMfbhNlE'
}
{
  exp: 1663097129,
  iat: 1663064741,
  auth_time: 1663061129,
  jti: '35c41b2f-1077-45f3-bac8-87f1ae20650b',
  iss: 'http://localhost:8180/auth/realms/nodejs-example',
  aud: 'account',
  sub: '99aa0ed3-29c1-457a-868f-25ce9a931d03',
  typ: 'Bearer',
  azp: 'nodejs-connect',
  session_state: '4ff4ac4b-e939-4af3-ba43-f5869fa386cd',
  acr: '0',
  realm_access: {
    roles: [
      'offline_access',
      'uma_authorization',
      'default-roles-nodejs-example'
    ]
  },
  resource_access: { account: { roles: [Array] } },
  scope: 'openid email profile',
  sid: '4ff4ac4b-e939-4af3-ba43-f5869fa386cd',
  email_verified: false,
  preferred_username: 'admin-user'
}
<Buffer 17 eb bb 40 8b a4 bb cd 5f e5 ee 84 00 f7 5d 2a 59 44 ff cc 46 c3 bc c5 d0 6a e5 3e ca 94 60 e0 1d 22 5c 0b bc 8a c2 8d d2 e1 da 5d 4f 99 ca 44 e0 9e ... 78 more bytes>
nodejs-connect

Debugging in VS code enter image description here

Node.js相关问答推荐

无法在我的 node 项目中转让Google Drive v3 API中的所有权

查询嵌套数组中的最后一个元素具有特定值的mongoDB集合中的文档

Express 4.18正文解析

MongoDB-如何验证Document字段以仅允许特定的文件扩展名?

如何使用Nextjs路由从下一步/导航在新选项卡中通过";router.ush";打开链接

构建期间 Docker 容器中的 npm 安装失败

如何获取mongoose中单个id数据的记录

如何使用Stripe测试失败的收费?

无法截取页面截图

在 linux mint 上部署 node 应用程序的最简单方法是什么?

如何修改这个flake.nix,这样我就不用每次加载环境都加载nix包了

无法使用 node 预签名 url 从 React 将图像文件上传到 s3

如何在没有 Typescript 的情况下以交互方式使用 Create-React-App?

如何解决 npm install react-select failure with error : An unknown git error occurred, git@github.com :Permission denied (publickey)

tsc:当我上传 React+next js 和 node 项目时,在 heroku 找不到

为什么 req.params.id 返回 undefined未定义?

如何将`yarn.lock`与`package.json`同步?

使用 pm2 编程 api 重命名进程

在 Jade 包含中使用变量

Firestore:多个条件 where 子句