const express = require("express");
const router = express.Router();
const axios = require("axios");
const querystring = require("querystring");
const dotenv = require("dotenv");
const session = require("express-session");
const MemoryStore = require("memorystore")(session);
dotenv.config();
const client_id = "27905";
const client_secret = "NEVER SHARE THIS!!!REMOVED";
const redirect_uri = `${process.env.SERVER_URL}/stackoverflow/callback`;
const sessionConfig = {
secret: "your_secret_key", // Change this to a strong, unique secret
resave: false,
saveUninitialized: true,
store: new MemoryStore({
checkPeriod: 86400000, // prune expired entries every 24h
}),
cookie: {
maxAge: 86400000, // 24 hours
},
};
router.use(session(sessionConfig));
function generateRandomString(length) {
const charset =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let result = "";
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
result += charset.charAt(randomIndex);
}
return result;
}
router.get("/login", (req, res) => {
try {
const state = generateRandomString(16);
const scopes = "read_inbox write_access";
// Save state in the session to validate it later in the callback
req.session.linkedinState = state;
res.redirect(
"https://stackoverflow.com/oauth?" +
querystring.stringify({
client_id: client_id,
scope: scopes,
redirect_uri: redirect_uri,
state: state,
})
);
} catch (err) {
console.log("Server error");
console.error(err);
res.status(500).json({
success: false,
message: "Server error",
});
}
});
router.get("/callback", async (req, res) => {
try {
const code = req.query.code || null;
const state = req.query.state || null;
const storedState = req.session.linkedinState;
// Validate state to prevent CSRF attacks
if (state === null || state !== storedState) {
return res.status(403).json({
success: false,
message: "Invalid state parameter",
});
}
// Clear the state from the session
delete req.session.linkedinState;
// Exchange the authorization code for an access token
const tokenResponse = await axios.post(
"https://stackoverflow.com/oauth/access_token",
querystring.stringify({
client_id: client_id,
client_secret: client_secret,
code: code,
redirect_uri: redirect_uri,
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
const accessToken = tokenResponse.data;
// Store the access token securely (e.g., in the session)
req.session.stackOverflowAccessToken = accessToken;
// Redirect or perform any other action after successful authentication
res.redirect(`http://localhost:3000/?${accessToken}`);
} catch (err) {
console.log("Server error at callback");
console.error(err);
res.status(500).json({
success: false,
message: "Server error at callback",
});
}
});
module.exports = router;
-
You have leaked your client-secret. You should regenerate it.– rene ♦Commented Dec 9, 2023 at 18:00
Add a comment
|