0

I am using keycloak21.0.2 in a docker container. When I try to make a get request from frontend react app.

Example:

  const fetchProducts = async () => {
    try {
      if (keycloak.authenticated) {
        const token = keycloak.token;
        const res = await axios.get('/products', {
          headers: {
            'Authorization': `Bearer ${token}`,
          },
        });

        setProducts(res.data);
      }
    } catch (err) {
      console.error(err);
    }
  };

The error I get is

Access to XMLHttpRequest at 'http://localhost:8080/realms/project-realm/protocol/openid-connect/auth?client_id=project-api&state=294ff742-1f88-404b-8207-1ce4301fb9d2&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fproducts%3Fauth_callback%3D1&scope=openid&response_type=code' (redirected from 'http://localhost:5000/products') from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

My react app client in keycloak is public type and is properly working on the frontend after logging in. Bearer token is properly passed to the API but it cors blocks it. I even have origin set to origin: '*', even though It is a bad practice it still does not make it work.

This is my api client config

For backend I have client authentication and authorization turned on. Config for frontend is very similiar as in the picture above it's just localhost:3000 instead of localhost:5000.

My api connected to mongodb database looks like that

const bodyParser = require('body-parser');
const express = require('express');
const {NodeAdapter} = require('ef-keycloak-connect');
const mongoose = require('mongoose');
const cors=require("cors");
const session = require('express-session');

const memoryStore = new session.MemoryStore();
const app = express();

const config = {
  "realm": "project-realm",
  "auth-server-url": "http://localhost:8080/",
  "ssl-required": "external",
  "resource": "project-api",
  "verify-token-audience": true,
  "credentials": {
      "secret": "secret"
  },
  "confidential-port": 0,
  "policy-enforcer": {}
}

const keycloak = new NodeAdapter(config);

app.use(cors({
  origin: '*'
}));

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.use(session({
  secret: 'secret',
  resave: false,
  saveUninitialized: true,
  store: memoryStore
}));

app.use(keycloak.middleware());


const productsRouter = require('./routes/products');
app.use('/products', keycloak.protect(), productsRouter);

and an example route

router.get('/', async (req, res) => {
  try {
    const roles = req.kauth.grant?.access_token.content.realm_access.roles;
    const isAdmin = roles?.some(role => role === 'admin');
    let products;

    if (isAdmin) {
      products = await Product.find({});
    } else {
      products = await Product.find({ isPublic: true });
    }
    res.json(products);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

I tried changing webOrigins to * on both clients and adding cors with origin * to the api. I also tried adding different headers in the frontend. Nothing really helped and I suspect it's an issue with keycloak config or logic of my app. I doubt it's just a normal cors error.

czxriken
  • 25
  • 4
  • 1
    Question is why is your react frontend trying to redirect to keycloak 8080 although it already has a token, as you said. – Matthias Wiedemann Jun 19 '23 at 16:49
  • What should I do in this situation? My frontend is public type and it gets an access token but api has client ID and secret for keycloak. If you know what I should focus on changing I would greatly appreciate it if you told me since using keycloak is very frustrating with not much documentation and online resources for these new versions. – czxriken Jun 19 '23 at 16:56
  • on this graph I tried comparing structure of my app to the one on the graph, but I don't really get it, my front is secured by keycloak and then I pass the access token to the api, but the api is secured by keycloak through keycloak.middleware() with keycloak.protect() on certain routes https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow – czxriken Jun 19 '23 at 17:18
  • Does it mean that the access token is not correct and I'm not authenticated, that's why I get redirected? – czxriken Jun 19 '23 at 17:28

0 Answers0