Bird
Raised Fist0
Expressframework~20 mins

Resource ownership checks in Express - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Resource Ownership Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What is the output when a user tries to delete a resource they do not own?

Consider this Express route that deletes a post only if the logged-in user owns it.

app.delete('/posts/:id', (req, res) => {
  const post = posts.find(p => p.id === req.params.id);
  if (!post) return res.status(404).send('Post not found');
  if (post.ownerId !== req.user.id) return res.status(403).send('Forbidden');
  posts = posts.filter(p => p.id !== req.params.id);
  res.send('Deleted');
});

If req.user.id is 'user2' and the post owner is 'user1', what will the response be?

Express
app.delete('/posts/:id', (req, res) => {
  const post = posts.find(p => p.id === req.params.id);
  if (!post) return res.status(404).send('Post not found');
  if (post.ownerId !== req.user.id) return res.status(403).send('Forbidden');
  posts = posts.filter(p => p.id !== req.params.id);
  res.send('Deleted');
});
AStatus 200 with message 'Deleted'
BStatus 404 with message 'Post not found'
CStatus 403 with message 'Forbidden'
DStatus 500 with server error
Attempts:
2 left
💡 Hint

Check the ownership condition before deleting.

📝 Syntax
intermediate
2:00remaining
Which option correctly checks resource ownership in Express middleware?

Choose the correct middleware snippet that verifies if the logged-in user owns the resource before proceeding.

A
function checkOwner(req, res, next) {
  if (req.resource.owner !== req.user.id) {
    return res.status(403).send('Forbidden');
  }
  next();
}
B
function checkOwner(req, res, next) {
  if (req.resource.owner = req.user.id) {
    next();
  } else {
    res.status(403).send('Forbidden');
  }
}
C
function checkOwner(req, res, next) {
  if (req.resource.owner !== req.user) {
    return res.status(403).send('Forbidden');
  }
  next();
}
D
function checkOwner(req, res, next) {
  if (req.resource.owner !== req.user.id) {
    next();
  } else {
    res.status(403).send('Forbidden');
  }
}
Attempts:
2 left
💡 Hint

Remember to use strict comparison and call next() only if ownership matches.

🔧 Debug
advanced
2:00remaining
Why does this ownership check always allow deletion?

Examine this Express route:

app.delete('/items/:id', (req, res) => {
  const item = items.find(i => i.id === req.params.id);
  if (!item) return res.status(404).send('Not found');
  if (item.ownerId = req.user.id) {
    items = items.filter(i => i.id !== req.params.id);
    return res.send('Deleted');
  }
  res.status(403).send('Forbidden');
});

Why does this code allow any user to delete any item?

Express
app.delete('/items/:id', (req, res) => {
  const item = items.find(i => i.id === req.params.id);
  if (!item) return res.status(404).send('Not found');
  if (item.ownerId = req.user.id) {
    items = items.filter(i => i.id !== req.params.id);
    return res.send('Deleted');
  }
  res.status(403).send('Forbidden');
});
ABecause '=' is used instead of '===' causing assignment instead of comparison
BBecause items.filter does not remove the item correctly
CBecause req.user.id is undefined causing the check to fail
DBecause the route does not call next() middleware
Attempts:
2 left
💡 Hint

Look carefully at the if condition syntax.

state_output
advanced
2:00remaining
What is the state of the posts array after this ownership check and deletion?

Given this initial posts array:

let posts = [
  { id: '1', ownerId: 'user1' },
  { id: '2', ownerId: 'user2' },
  { id: '3', ownerId: 'user1' }
];

And this Express route:

app.delete('/posts/:id', (req, res) => {
  const post = posts.find(p => p.id === req.params.id);
  if (!post) return res.status(404).send('Not found');
  if (post.ownerId !== req.user.id) return res.status(403).send('Forbidden');
  posts = posts.filter(p => p.id !== req.params.id);
  res.send('Deleted');
});

If req.user.id is 'user1' and the request is to delete post with id '2', what will be the posts array after the request?

Express
let posts = [
  { id: '1', ownerId: 'user1' },
  { id: '2', ownerId: 'user2' },
  { id: '3', ownerId: 'user1' }
];

app.delete('/posts/:id', (req, res) => {
  const post = posts.find(p => p.id === req.params.id);
  if (!post) return res.status(404).send('Not found');
  if (post.ownerId !== req.user.id) return res.status(403).send('Forbidden');
  posts = posts.filter(p => p.id !== req.params.id);
  res.send('Deleted');
});
A[]
B[{ id: '1', ownerId: 'user1' }, { id: '3', ownerId: 'user1' }]
C[{ id: '2', ownerId: 'user2' }]
D[{ id: '1', ownerId: 'user1' }, { id: '2', ownerId: 'user2' }, { id: '3', ownerId: 'user1' }]
Attempts:
2 left
💡 Hint

Check if the ownership condition allows deletion.

🧠 Conceptual
expert
2:00remaining
Which is the best practice to ensure resource ownership in an Express app?

Choose the best approach to enforce resource ownership checks across multiple routes in an Express application.

AAdd ownership checks inside each route handler manually
BUse a dedicated middleware that loads the resource and verifies ownership before route handlers
CTrust the client to send only owned resource IDs and skip server checks
DCheck ownership only after performing the resource modification
Attempts:
2 left
💡 Hint

Think about code reuse and security.

Practice

(1/5)
1. What is the main purpose of resource ownership checks in an Express app?
easy
A. To allow any user to edit any resource
B. To ensure only the owner can access or modify their resource
C. To speed up database queries
D. To log user activity for analytics

Solution

  1. Step 1: Understand resource ownership

    Resource ownership means a resource belongs to a specific user.
  2. Step 2: Purpose of ownership checks

    Ownership checks prevent unauthorized users from accessing or changing resources they don't own.
  3. Final Answer:

    To ensure only the owner can access or modify their resource -> Option B
  4. Quick Check:

    Ownership check = restrict access to owner [OK]
Hint: Ownership checks block non-owners from resource access [OK]
Common Mistakes:
  • Thinking ownership checks speed up queries
  • Allowing all users to edit resources
  • Confusing ownership with logging
2. Which Express middleware pattern correctly checks if the logged-in user owns a resource with ID in req.params.id and owner ID in resource.ownerId?
easy
A. if (req.user.id == resource.owner) { next(); } else { res.status(401).send('Unauthorized'); }
B. if (req.user === resource.ownerId) { next(); } else { res.status(404).send('Not Found'); }
C. if (req.user.id === resource.ownerId) { next(); } else { res.status(403).send('Forbidden'); }
D. if (req.user.id !== resource.ownerId) { next(); } else { res.status(403).send('Forbidden'); }

Solution

  1. Step 1: Check user ID equality

    We compare req.user.id with resource.ownerId using strict equality to confirm ownership.
  2. Step 2: Respond with 403 if not owner

    If IDs don't match, respond with 403 Forbidden to block access.
  3. Final Answer:

    if (req.user.id === resource.ownerId) { next(); } else { res.status(403).send('Forbidden'); } -> Option C
  4. Quick Check:

    Strict equality + 403 Forbidden = correct ownership check [OK]
Hint: Use strict equality and 403 status for ownership checks [OK]
Common Mistakes:
  • Using == instead of ===
  • Sending wrong status codes like 404 or 401
  • Comparing whole user object instead of user ID
3. Given this Express route snippet, what will happen if req.user.id is '123' and resource.ownerId is '456'?
app.delete('/items/:id', (req, res) => {
  const resource = {ownerId: '456'};
  if (req.user.id === resource.ownerId) {
    res.send('Deleted');
  } else {
    res.status(403).send('Forbidden');
  }
});
medium
A. The item will be deleted and 'Deleted' sent
B. The server will crash due to undefined resource
C. Response will be 404 Not Found
D. Response will be 403 Forbidden

Solution

  1. Step 1: Compare user ID and owner ID

    Since req.user.id ('123') does not equal resource.ownerId ('456'), ownership check fails.
  2. Step 2: Return 403 Forbidden

    The else block sends a 403 Forbidden response blocking deletion.
  3. Final Answer:

    Response will be 403 Forbidden -> Option D
  4. Quick Check:

    Non-matching IDs = 403 Forbidden [OK]
Hint: Non-owner gets 403 Forbidden response [OK]
Common Mistakes:
  • Assuming deletion happens anyway
  • Confusing 403 with 404
  • Ignoring ownership check logic
4. Identify the bug in this ownership check middleware:
function checkOwnership(req, res, next) {
  const resource = {ownerId: '456'}; /* example */
  if (req.user.id = resource.ownerId) {
    next();
  } else {
    res.status(403).send('Forbidden');
  }
}
medium
A. Using assignment (=) instead of comparison (===) in the if condition
B. Missing call to next() in else block
C. Incorrect status code; should be 404 instead of 403
D. resource.ownerId is undefined

Solution

  1. Step 1: Check the if condition syntax

    The condition uses single equals (=), which assigns instead of compares, causing a bug.
  2. Step 2: Correct comparison operator

    It should use strict equality (===) to compare req.user.id and resource.ownerId.
  3. Final Answer:

    Using assignment (=) instead of comparison (===) in the if condition -> Option A
  4. Quick Check:

    Assignment in if condition = bug [OK]
Hint: Use === for comparison, not = assignment [OK]
Common Mistakes:
  • Confusing = with === in conditions
  • Thinking next() needed in else block
  • Wrong status code for forbidden access
5. You want to protect a route so only the owner of a blog post can edit it. The post's owner ID is stored in post.ownerId. Which Express middleware correctly implements this ownership check and returns 403 if the user is not the owner?
hard
A. app.put('/posts/:id', (req, res, next) => { if (req.user.id === post.ownerId) next(); else res.status(403).send('Forbidden'); }, (req, res) => { res.send('Post updated'); });
B. app.put('/posts/:id', (req, res) => { if (req.user.id !== post.ownerId) res.status(403).send('Forbidden'); else res.send('Post updated'); });
C. app.put('/posts/:id', (req, res, next) => { if (req.user.id == post.ownerId) next(); else res.status(404).send('Not Found'); }, (req, res) => { res.send('Post updated'); });
D. app.put('/posts/:id', (req, res) => { if (req.user.id === post.ownerId) res.send('Post updated'); else res.status(401).send('Unauthorized'); });

Solution

  1. Step 1: Use middleware to check ownership before update

    Middleware checks if req.user.id matches post.ownerId and calls next() if true.
  2. Step 2: Return 403 Forbidden if not owner

    If IDs don't match, respond with 403 to block unauthorized edits.
  3. Final Answer:

    app.put('/posts/:id', (req, res, next) => { if (req.user.id === post.ownerId) next(); else res.status(403).send('Forbidden'); }, (req, res) => { res.send('Post updated'); }); -> Option A
  4. Quick Check:

    Middleware + strict equality + 403 Forbidden = correct pattern [OK]
Hint: Use middleware with strict check and 403 response [OK]
Common Mistakes:
  • Using == instead of ===
  • Sending wrong status codes like 404 or 401
  • Not using middleware pattern for ownership check