How can i implement logout feature in NodeJs with keycloak - node.js

I'm trying to implement a logout functionality with keycloaks which is running as a docker container.
When tried with postman I'm getting a 204 response, even after that I am able to access the web pages without having to login again (Hence logout has not happened correctly).
I have supplied the bearer token, client id, client secret and refresh token.
Please see the screenshots below from Postman.
Similarly have tried to implement these changes on nodejs using axios.But however things are not working.
var axios = require('axios');
var qs = require('qs');
var data = qs.stringify({
'client_id': 'VideoKYC',
'client_secret': 'my-clinet-secret',
'refresh_token': 'refresh token from cookies'
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0
var config = {
method: 'post',
url: 'https://3.109.1.86:8443/auth/realms/VideoKYC-Realm/protocol/openid-connect/logout',
headers: {
'Authorization': 'Bearer my-token',
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
};
axios(config)
.then(function (response) {
console.log("data is");
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Stack trace from where response is empty:
$ node logout.js
(node:16732) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
data is
""
Ideally I think we should get some response, and the token should be invalidated and automatically be logged out.
Please help me implement these changes

this code works for me.
const data = qs.stringify({
client_id: 'your_kc_clientId',
client_secret: 'your_kc_client_secret',
refresh_token: 'your_referesh_token',
});
const config = {
method: 'post',
url: `${process.env.KEYCLOAK_SERVER_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/logout`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
data: data,
};
axios(config)
.then((response) => console.log('logout successfully'))
.catch((err) => console.log('error!!!'));

Related

Node.js? API Authentication problems

This is what my "dev" sent me. Someone help please
I'm trying my best, but their API doesn't respond to our methods. This authentication is the root of the problem. I'm right now using Axios(the most popular and only method for making API requests for web apps) but it's not accepting request
and then i told him i would ask for help*
You can ask this question- ` How do I make requests for creating order API in my express app? I've tried to make the request by getting my form data from my EJS form using the request.body. But still, it is saying error 400.
Here is his code:
app.post('/order-labels', checkAuthenticated, (req, res) => {
const data = JSON.stringify(req.body);
console.log(data)
const config = {
method: 'post',
url: 'https://labelsupply.io/api/order',
headers: {
'X-Api-Auth': '32854090-03dd-a3c1-Deleted some for safety',
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
};
axios(config)
.then(function(response) {
console.log(response.data);
})
.catch(function(error) {
console.log(error);
});
})
by console.logging we are getting the data, but the API doesn't accepting
The API Docs are here.
you may need an account to view just put junk
The API calls for url encoded string.
const data = JSON.stringify(req.body);
console.log(data)
data = new URLSearchParams(Object.entries(data)).toString();
console.log(data); // now should be URL encoded
const config = {
method: 'post',
url: 'https://labelsupply.io/api/order',
headers: {
'X-Api-Auth': '32854090-03dd-a3c1-Deleted some for safety',
'Content-Type': 'application/x-www-form-urlencoded'
},
data: data
};
See if the API likes the new encoding?

When I use Discord OAuth2 I am getting error 400. How can I make this return the access_token correctly?

I am unable to get the clients identiy through discords oauth2. First we do this:
https://discord.com/api/oauth2/authorize?client_id=9999999999999&redirect_uri=http%3A%2F%2Fxxxx.xyz%2F&response_type=code&scope=identify
to get their code. Which seems to work fine.
let options = {
url: 'https://discord.com/api/oauth2/token',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
'client_id': '9999999999999',
'client_secret': 'MYSECRETHERE',
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': 'https://xxxx.xyz/callback',
'scope': 'identify'
}).toString()
};
await fetch("https://discord.com/api/oauth2/token", options)
.then(handleErrors)
.then(response => response.json())
.then(response => {
access_token = response.access_token;
}).catch(function(error) {
console.log(error);
});
What happens here is I get a error 400 instead of the access token. Originally the 'grant_type' was set as client_credientals but I realized that this only grabs the identity of the application owner itself, not others. This worked however. Changing it to authorization_code however does not.
Any suggestions?
Compared to the token exchange example, you are passing scope in the request – that shouldn't be there. Scope is passed only in the initial authorization URL.

API call from https node application never reaches the destination

I have a node.js application served over https. I would like to call an API from that application. The API is also served over https and it has been generated using the express-generator.
Unfortunately the call never works. There is no error message. The call never reaches the API.
Strangely enough if I try to call another public API (e.g. https://api.publicapis.org/entries') that is working perfectly.
Here is my call:
const requestBody = {
'querystring': searchQuery,
};
const options = {
rejectUnauthorized: false,
keepAlive: false, // switch to true if you're making a lot of calls from this client
};
return new Promise(function (resolve, reject) {
const sslConfiguredAgent = new https.Agent(options);
const requestOptions = {
method: 'POST',
body: JSON.stringify(requestBody),
agent: sslConfiguredAgent,
redirect: 'follow',
};
fetch('https://192.168.112.34:3003/search', requestOptions)
.then(response => response.text())
.then(result => resolve(result))
.catch(error => console.log('error', error));
});
};
And here is the API which I would like to call:
router.post('/', cors(), async function(req, res, next) {
req.body;
queryString = req.body.querystring;
let data = JSON.stringify({
"query": {
"match": {
"phonetic": {
"query": queryString,
"fuzziness": "AUTO",
"operator": "and"
}
}
}
});
const { body } = await client.search({
index: 'phoneticindex',
body: data
});
res.send(body.hits.hits)
});
What is wrong with my API and/or the way I am trying to communicate with it?
UPDATE: I receive the following error in the fetch catch block: 'TypeError: Failed to fetch'
When I create a request in Postman I receive the expected response.
UPDATE 2: This is most probably an SSL related issue. The webapp is expecting an API with a valid certificate. Obviously my API can only have a self signed cert which is not enough here. How can I generate a valid cert for an API which is running on the local network and not publicly available?
UPDATE 3: I managed to make it work by changing the fetch parameters like this:
fetch(url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
mode: 'cors',
body: raw,
agent: httpsAgent,
redirect: 'follow',
})
and on the API side I added the following headers:
'Content-Type': 'application/json',
'Access-Control-Allow-Origin' : 'https://localhost:2200',
'Access-Control-Allow-Methods' : 'POST',
'Access-Control-Allow-Headers' : 'Content-Type, Authorization'
I also added app.use(cors()) and regenerated the self-signed certificates.

node-fetch send post request with body as x-www-form-urlencoded

i want to send a post request using node-fetch with a body payload encoded in the x-www-form. I tried this code but unfortunately it doesnt work:
paypalSignIn = function(){
var username = process.env.PAYPALID;
var password = process.env.PAYPALSECRET;
var authContent = 'Basic '+base64.encode(username + ":" + password);
fetch('https://api.sandbox.paypal.com/v1/oauth2/token', { method: 'POST',
headers: {
'Accept': 'application/json',
'Accept-Language' :"en_US",
'Authorization': authContent,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials' })
.then(res => res.json()) // expecting a json response
.then(json => console.log(json));
}
I'm not sure if this way is possible but i need to use this standard for die paypal api.
I'm getting statu code 400 with error
grant_type is null
Thx
I don't know if this is the only error, but at the very least you need a space between the word Basic and the encoded username/password.
Next time you ask a question, also post what your script returned. I'm guessing it was a 401 error in this case.
I used the PayPal sandbox today, here is how I managed to get my access token and a successful response (and also answering the OP's question about sending application/x-www-form-urlencoded POST requests with data) =>
I did it with node-fetch but the plain fetch API should work the same.
import fetch from "node-fetch";
export interface PayPalBusinessAccessTokenResponseInterface {
access_token: string;
}
export interface PayPalClientInterface {
getBusinessAccessToken: (
clientId: string,
clientSecret: string
) => Promise<PayPalBusinessAccessTokenResponseInterface>
}
const paypalClient: PayPalClientInterface = {
async getBusinessAccessToken(
clientId: string,
clientSecret: string
): Promise<PayPalBusinessAccessTokenResponseInterface> {
const params = new URLSearchParams();
params.append("grant_type", "client_credentials");
const paypalAPICall = await fetch(
"https://api-m.sandbox.paypal.com/v1/oauth2/token",
{
method: "POST",
body: params,
headers: {
"Authorization": `Basic ${Buffer.from(clientId + ":" + clientSecret).toString('base64')}`
}
}
);
const paypalAPIRes = await paypalAPICall.json();
return paypalAPIRes;
}
};
export default paypalClient;

Unexpected token N in JSON at position 0

guys. I have a than error in my NodeJS rest API, and can't resolve this.
My idea is make a github login, this app working like this.
Href to github url returning a temporal code in callback.
Latter, send this temporal code to my REST API and with rest api make a fetch request to other endpoint of the github api, and this endpoint should return access_token=12345 (this access token is a example), for latter send this token to frontend, and convert the token in a JWT token and also send to frontend for latter storage in a localStorage to use it.
My code in NodeJS
router.post("/users/github/:code",function(req,res){
fetch('https://github.com/login/oauth/access_token/', {
method: 'GET',
client_id: 'xxxx',
client_secret: 'xxxx',
code: req.params.code,
accept: 'json',
})
.then(function(res) {
return res.json();
}).then(function(json) {
console.log(json);
});
});
PD: I use node-fetch module for this. https://www.npmjs.com/package/node-fetch
The solution
router.post("/users/github/:code",function(req,res){
fetch('https://github.com/login/oauth/access_token/', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
client_id: 'xxxx',
client_secret: 'xxxx',
code: req.params.code
})
}).then(function(res) {
return res.json();
}).then(function(body) {
res.json(body);
});
});

Resources