mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-22 17:22:04 -07:00
Achieving desired rate limiting results.
This commit is contained in:
+1
-1
@@ -76,7 +76,7 @@ app.use(`/${v3prefix}/`, auth.mw())
|
|||||||
|
|
||||||
// Rate limit on all v3 routes
|
// Rate limit on all v3 routes
|
||||||
app.use(`/${v3prefix}/`, routeRateLimit) // Establish and enforce rate limits.
|
app.use(`/${v3prefix}/`, routeRateLimit) // Establish and enforce rate limits.
|
||||||
app.use(`/${v3prefix}/`, jwtAuth.routeAccess) // Enforce access tiers.
|
// app.use(`/${v3prefix}/`, jwtAuth.routeAccess) // Enforce access tiers.
|
||||||
app.use(`/${v3prefix}/` + `health-check`, healthCheckV3)
|
app.use(`/${v3prefix}/` + `health-check`, healthCheckV3)
|
||||||
app.use(`/${v3prefix}/` + `blockchain`, blockchainV3.router)
|
app.use(`/${v3prefix}/` + `blockchain`, blockchainV3.router)
|
||||||
app.use(`/${v3prefix}/` + `control`, controlV3.router)
|
app.use(`/${v3prefix}/` + `control`, controlV3.router)
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ const routeAccess = (req, res, next) => {
|
|||||||
// API Level is 0 (free tier): do nothing. All endpoints are open to
|
// API Level is 0 (free tier): do nothing. All endpoints are open to
|
||||||
// free public access within the drastically limited rate limits.
|
// free public access within the drastically limited rate limits.
|
||||||
|
|
||||||
if (locals.apiLevel === 10) {
|
if (locals.apiLevel < 20) {
|
||||||
// API level is 10 (full node tier)
|
// API level does not include indexer access.
|
||||||
|
|
||||||
// Loop through the routes that are not accessible to this tier.
|
// Loop through the routes that are not accessible to this tier.
|
||||||
for (let i = 0; i < level20Routes.length; i++) {
|
for (let i = 0; i < level20Routes.length; i++) {
|
||||||
|
|||||||
@@ -53,17 +53,35 @@ const routeRateLimit = async function(req, res, next) {
|
|||||||
if (req.locals.jwtToken) {
|
if (req.locals.jwtToken) {
|
||||||
// console.log(`req.locals.jwtToken: ${req.locals.jwtToken}`)
|
// console.log(`req.locals.jwtToken: ${req.locals.jwtToken}`)
|
||||||
|
|
||||||
|
// URL for the auth server.
|
||||||
const path = `${authServer}apitoken/isvalid/${req.locals.jwtToken}`
|
const path = `${authServer}apitoken/isvalid/${req.locals.jwtToken}`
|
||||||
|
|
||||||
|
// Ask Auth server if the JWT token is valid.
|
||||||
|
// Get the API level for this user.
|
||||||
let jwtInfo = await axios.get(path)
|
let jwtInfo = await axios.get(path)
|
||||||
jwtInfo = jwtInfo.data
|
jwtInfo = jwtInfo.data
|
||||||
// console.log(`jwtInfo: ${JSON.stringify(jwtInfo, null, 2)}`)
|
console.log(`jwtInfo: ${JSON.stringify(jwtInfo, null, 2)}`)
|
||||||
|
|
||||||
// Enable pro-tier rate limits if JWT if valid.
|
// If JWT if valid, evaluate the API level for the user.
|
||||||
if (jwtInfo.isValid) {
|
if (jwtInfo.isValid) {
|
||||||
// console.log(`JWT is valid. Enabling pro-tier rate limits.`)
|
// Set fine-grain permissions for each user based on the JWT token.
|
||||||
req.locals.proLimit = true
|
const userPermissions = evalUserPermissioins(req, jwtInfo)
|
||||||
req.locals.apiLevel = jwtInfo.apiLevel
|
console.log(
|
||||||
|
`userPermissions: ${JSON.stringify(userPermissions, null, 2)}`
|
||||||
|
)
|
||||||
|
console.log(` `)
|
||||||
|
|
||||||
|
req.locals.proLimit = userPermissions.proLimit
|
||||||
|
req.locals.apiLevel = userPermissions.apiLevel
|
||||||
|
|
||||||
|
// const locals = req.locals
|
||||||
|
// console.log(`locals: ${JSON.stringify(locals, null, 2)}`)
|
||||||
|
// const url = req.url
|
||||||
|
// console.log(`url: ${JSON.stringify(url, null, 2)}`)
|
||||||
|
//
|
||||||
|
// // console.log(`JWT is valid. Enabling pro-tier rate limits.`)
|
||||||
|
// req.locals.proLimit = true
|
||||||
|
// req.locals.apiLevel = jwtInfo.apiLevel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,7 +144,7 @@ const routeRateLimit = async function(req, res, next) {
|
|||||||
|
|
||||||
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
res.status(429) // https://github.com/Bitcoin-com/rest.bitcoin.com/issues/330
|
||||||
return res.json({
|
return res.json({
|
||||||
error: `Too many requests. Limits are ${maxRequests} requests per minute.`
|
error: `Too many requests. Your limits are currently ${maxRequests} requests per minute.`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -139,4 +157,39 @@ const routeRateLimit = async function(req, res, next) {
|
|||||||
uniqueRateLimits[route](req, res, next)
|
uniqueRateLimits[route](req, res, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function returns the an object with proLimit and apiLevel properties.
|
||||||
|
// It does fine-grane analysis on the data coming from the auth servers and
|
||||||
|
// uses its output to adjust rate limits on-the-fly based on the users
|
||||||
|
// permission level.
|
||||||
|
function evalUserPermissioins(req, authData) {
|
||||||
|
console.log(`authData: ${JSON.stringify(authData, null, 2)}`)
|
||||||
|
|
||||||
|
// Return object with default values
|
||||||
|
const retObj = {
|
||||||
|
proLimit: authData.isValid,
|
||||||
|
apiLevel: authData.apiLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
const level20Routes = ["insight", "bitcore", "blockbook"]
|
||||||
|
|
||||||
|
const locals = req.locals
|
||||||
|
console.log(`locals: ${JSON.stringify(locals, null, 2)}`)
|
||||||
|
const url = req.url
|
||||||
|
console.log(`url: ${JSON.stringify(url, null, 2)}`)
|
||||||
|
|
||||||
|
if (authData.apiLevel < 20) {
|
||||||
|
// Loop through the routes that are not accessible to this tier.
|
||||||
|
for (let i = 0; i < level20Routes.length; i++) {
|
||||||
|
// If the requested route is for a higher tier,
|
||||||
|
// revert to anonymous level permissions.
|
||||||
|
if (url.indexOf(level20Routes[i]) > -1) {
|
||||||
|
retObj.proLimit = false
|
||||||
|
retObj.apiLevel = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retObj
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { routeRateLimit }
|
module.exports = { routeRateLimit }
|
||||||
|
|||||||
Reference in New Issue
Block a user