Trying to do LinkedIn Authorization Code Flow (3-legged OAuth) but I keep getting this error 'Unable to retrieve access token: appid/redirect uri/code verifier does not match authorization code. Or authorization code expired. Or external member binding exists' and I tested it on postman with the same params and it worked fine but it won't work in my app I don't know what I am doing wrong
I am using passportjs and I did the first step which is To request an authorization code, you must direct the member's browser to LinkedIn's OAuth 2.0 authorization page, where the member either accepts or denies your application's permission request. and that's working I get back the code that I need but then inside the try catch the post request is not working even tho all the params
are correct
const passport = require("passport");
const User = require("../models/User");
const LinkedInStrategy = require("passport-linkedin-oauth2").Strategy;
const axios = require("axios");
const callbackURL = `${process.env.FRONTEND_URL}/`;
const authenticate = (req, res, next) => {
passport.use(
new LinkedInStrategy(
{
clientID: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
callbackURL: `${process.env.SERVER_URL}/api/v1/auth/linkedin/callback`,
profileFields: ["id", "displayName", "email", "picture.type(large)"],
passReqToCallback: true,
state: true,
scope: ["r_liteprofile", "r_emailaddress"],
},
async (req, accessToken, refreshToken, profile, done) => {
await axios.get(`https:
const { code } = req.query;
console.log("this is code", code);
try {
const tokenResponse = await axios.post(
"https://www.linkedin.com/oauth/v2/accessToken",
null,
{
params: {
grant_type: "authorization_code",
code: code,
client_id: process.env.LINKEDIN_CLIENT_ID,
client_secret: process.env.LINKEDIN_CLIENT_SECRET,
redirect_uri: `${process.env.SERVER_URL}/api/v1/auth/linkedin/callback`,
},
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
const accessToken = tokenResponse.data.access_token;
console.log("this is new access token", accessToken);
const profileResponse = await axios.get(
"https://api.linkedin.com/v2/me",
{
headers: {
Authorization: `Bearer ${accessToken}`,
},
}
);
const userProfile = profileResponse.data;
console.log("User Profile:", userProfile);
return tokenResponse.data.access_token;
} catch (error) {
console.error("Access Token Error:", error.message);
done(error);
}
}
)
);
passport.authenticate("linkedin",{
session: false,
})(req, res, next);
};
const callback = async (req, res) => {
passport.authenticate(
"linkedin",
{
failureRedirect: `${process.env.FRONTEND_URL}/channels?login=error&provider=linkedin`,
session: false,
},
function (err, page, info) {
console.log("err", err);
console.log("page", page);
console.log("info", info);
if (err) {
res.redirect(
`${process.env.FRONTEND_URL}/channels?login=error&provider=linkedin`
);
}
if (page) {
const expiryInMilliSecond = 1000 * 60 * 60 * 24 * 60;
const timestamp = Date.now() + expiryInMilliSecond;
res
.cookie("LinkedinPageAccessToken", page.linkedinUser.accessToken, {
httpOnly: true,
secure: true,
maxAge: expiryInMilliSecond,
})
.set("Access-Control-Allow-Credentials", "true");
res.cookie("LinkedinPageId", page.linkedinUser.id, {
maxAge: expiryInMilliSecond,
});
res.cookie("LinkedinExpiry", timestamp, {
maxAge: expiryInMilliSecond,
});
res.redirect(
`${process.env.FRONTEND_URL}/channels?login=success&provider=linkedin`
);
} else {
console.log("Linkedin auth failed");
res.redirect(
`${process.env.FRONTEND_URL}/channels?login=error&provider=linkedin`
);
}
}
)(req, res);
};
module.exports = { authenticate, callback };
What I have tried:
I made sure all my params are correct but its still not working