REST API Security: Authentication, Authorization, and Protective Measures
REST API security ensures that only authorized clients can access authorized resources. Anyone building APIs must understand authentication and authorization—they’re the foundation of every secure interface.
What is REST API Security?
REST API security encompasses all measures that protect a RESTful API from unauthorized access, manipulation, and attacks. It rests on two core pillars:
Authentication answers: Who are you? The client proves its identity through tokens, API keys, certificates, or session cookies.
Authorization answers: Are you allowed to do this? After authentication, the system checks whether the identified client has permission to perform the requested action.
This separation is essential. An authenticated user isn’t automatically authorized to do everything. A user can read their own data but not someone else’s. An admin can do more than an editor. This distinction is captured by models like RBAC (Role-Based Access Control) or ABAC (Attribute-Based Access Control).
Who uses REST API Security?
- Backend developers implement auth middleware and authorization logic
- API designers define which endpoints need which protection
- DevOps engineers configure TLS, rate limiting, and API gateways
- Security engineers audit APIs for vulnerabilities
- Frontend developers must send auth tokens correctly with requests
Why This Matters in Computer Science and Exams
The OWASP Top 10 lists Broken Access Control at number 1 and Cryptographic Failures at number 2—both directly affect API security. In professional certifications, computer science courses, and exams, questions regularly cover the differences between authentication and authorization, OAuth 2.0, JWT, and security headers.
Core Concepts in Detail
Authentication Methods for REST APIs
API Key
The client sends a static key in the X-API-Key header. The server compares it against its database.
Advantages: simple, works well for server-to-server communication. Disadvantages: no expiration, no granular permissions, full access if compromised.
Session-Based Authentication
The client sends credentials (username and password). The server creates a session, stores it on the server, and returns a session ID in a cookie. On each subsequent request, the cookie is sent automatically.
Advantages: server-side control, sessions can be invalidated at any time. Disadvantages: poor scaling across multiple instances (requires a shared session store), CSRF risk with cookies.
Token-Based Authentication (JWT)
The client sends credentials. The server creates a JSON Web Token (JWT) containing claims like user ID, roles, and expiration time. The token is cryptographically signed. The client sends it with each request in the Authorization: Bearer <token> header.
Advantages: stateless, scales well, no session store needed. Disadvantages: tokens can’t easily be revoked before expiration (except with revocation lists or blacklists).
OAuth 2.0
OAuth 2.0 is a framework for delegated authorization. A client obtains an access token from an authorization server after the resource owner (the user) grants consent. The token permits access to specific resources for a limited time.
Common flows:
- Authorization Code Flow: standard for web apps with a server backend
- PKCE Flow: for single-page applications and mobile apps without a client secret
- Client Credentials Flow: for server-to-server communication without user involvement
Authorization Models
RBAC (Role-Based Access Control)
Users are assigned roles. Roles have permissions. The check is: Does the user have a role that permits this action?
Example: the admin role can do anything, the editor role can read and write, the viewer role can only read.
Advantages: easy to understand, works well for manageable systems. Disadvantages: role explosion when permissions are very granular.
ABAC (Attribute-Based Access Control)
Access control is based on attributes of the subject, resource, action, and environment. The check is: Do all attribute combinations satisfy the policy?
Example: A doctor can read patient data only during working hours and only for patients in their department.
Advantages: very granular, policy-driven. Disadvantages: more complex to implement and maintain.
Resource Owner or Ownership-Based Authorization
A user can access only resources they own. An order can be viewed only by its owner. The check requires a database query: Does this resource belong to the authenticated user?
Additional Security Measures
TLS (Transport Layer Security)
Every API must run over HTTPS. Without TLS, tokens and credentials can be intercepted. TLS encrypts the transport channel and guarantees the integrity of transmitted data.
CORS (Cross-Origin Resource Sharing)
CORS controls which external origins may access the API.
The server sends Access-Control-Allow-Origin headers.
Without correct CORS configuration, browser-based clients may be blocked—or worse, arbitrary origins may gain access.
CSRF Protection
Cookie-based authentication carries CSRF risk. An attacker can trick a browser into automatically sending a cookie. Protective measures include CSRF tokens, the SameSite cookie attribute, and using the Authorization header instead of cookies.
Rate Limiting
Limits the number of requests per client within a time window. Protects against brute-force attacks, credential stuffing, and DoS. Typical: 100 requests per minute per token.
Input Validation
Every input must be validated. SQL injection, XSS, and command injection arise from missing or insufficient validation. Use prepared statements, schema validation, and whitelisting.
Why REST API Security Matters in Practice
An insecure API is an open door to your data. Here are realistic scenarios:
- Token leak: An access token is stored in logs or hardcoded in client code. An attacker finds it and gains access to all data belonging to that user.
- Broken Object Level Authorization (BOLA): The API checks only whether the user is authenticated, not whether they can access the requested resource. A user calls
/api/orders/42and sees another user’s order. - Mass Assignment: The client sends a field like
{"role":"admin"}during a profile update. The server accepts it unchecked. The user makes themselves an admin. - No Rate Limiting: An attacker tries 10,000 passwords per second. Without rate limiting, they crack the password in minutes.
Practical Example: Express.js API with JWT and RBAC
This example shows a complete REST API with authentication (JWT) and authorization (RBAC). It demonstrates the core concepts in compact code: token creation, middleware-based auth checks, role-based access control, and ownership verification.
// auth-middleware.js
// Middleware: Verifies JWT from the Authorization header
function authenticate(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({
error: 'UNAUTHORIZED',
message: 'Authentication required. Send a Bearer token.'
});
}
const token = authHeader.split(' ')[1];
try {
// jwt.verify throws an exception if the token is invalid or expired
const payload = jwt.verify(token, process.env.JWT_SECRET);
req.user = payload; // { userId: 42, role: 'editor', exp: 1234567890 }
next();
} catch (err) {
return res.status(401).json({
error: 'INVALID_TOKEN',
message: 'Token is invalid or expired.'
});
}
}
// Middleware: Checks whether the user has one of the required roles
function authorize(...roles) {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({
error: 'UNAUTHORIZED',
message: 'Authentication required.'
});
}
if (!roles.includes(req.user.role)) {
return res.status(403).json({
error: 'FORBIDDEN',
message: `Required role: ${roles.join(' or ')}.`
});
}
next();
};
}
// Middleware: Checks whether the user owns the resource
function checkOwnership(getResourceId) {
return async (req, res, next) => {
const resourceId = getResourceId(req);
const resource = await db.orders.findById(resourceId);
if (!resource) {
return res.status(404).json({
error: 'NOT_FOUND',
message: 'Resource not found.'
});
}
// Admins can access anything, others only their own resources
if (req.user.role !== 'admin' && resource.userId !== req.user.userId) {
return res.status(403).json({
error: 'FORBIDDEN',
message: 'You can only access your own resources.'
});
}
req.resource = resource;
next();
};
}
// routes.js
// Applying middleware to various endpoints
// Login: Authentication -> issue JWT
app.post('/api/login', async (req, res) => {
const { email, password } = req.body;
const user = await db.users.findByEmail(email);
if (!user || !await bcrypt.compare(password, user.passwordHash)) {
return res.status(401).json({
error: 'INVALID_CREDENTIALS',
message: 'Invalid email or password.'
});
}
const token = jwt.sign(
{ userId: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
res.json({ token });
});
// Protected routes: authenticate for all, authorize for specific roles
app.get('/api/orders', authenticate, async (req, res) => {
// Regular users see only their own orders
if (req.user.role === 'admin') {
const orders = await db.orders.findAll();
res.json(orders);
} else {
const orders = await db.orders.findByUserId(req.user.userId);
res.json(orders);
}
});
app.get('/api/orders/:id', authenticate, checkOwnership(req => req.params.id), (req, res) => {
res.json(req.resource);
});
app.post('/api/orders', authenticate, async (req, res) => {
const order = await db.orders.create({
...req.body,
userId: req.user.userId
});
res.status(201).json(order);
});
app.delete('/api/orders/:id', authenticate, authorize('admin'), checkOwnership(req => req.params.id), async (req, res) => {
await db.orders.delete(req.params.id);
res.status(204).send();
});
Detailed Information
Token Lifespan and Refresh Tokens
Access tokens should be short-lived (15 minutes). Refresh tokens last longer (days to weeks) and serve only to obtain new access tokens. If an access token is compromised, it remains useful only briefly. If a refresh token is compromised, it can be revoked server-side.
JWT Structure
A JWT consists of three Base64-encoded parts: header, payload, and signature. The header contains the algorithm and token type. The payload contains claims such as sub (subject), exp (expiration), iat (issued at), role, and userId. The signature is computed using a secret or private key.
Important: the payload is only Base64-encoded, not encrypted. Never store sensitive data in a JWT. Security comes from the signature—it guarantees the token hasn’t been tampered with.
Security Headers for REST APIs
| Header | Purpose |
|---|---|
Strict-Transport-Security | Enforces HTTPS |
X-Content-Type-Options: nosniff | Prevents MIME sniffing |
X-Frame-Options: DENY | Prevents clickjacking |
Cache-Control: no-store | Prevents caching of sensitive responses |
Access-Control-Allow-Origin | CORS configuration |
Common Vulnerabilities (OWASP API Security Top 10)
- BOLA (Broken Object Level Authorization): No ownership check
- Broken Authentication: Weak token creation, no rate limits
- Excessive Data Exposure: API returns more fields than necessary
- Lack of Resources & Rate Limiting: No request throttling
- Broken Function Level Authorization: No role checks per endpoint
- Mass Assignment: Unfiltered acceptance of input fields
- Security Misconfiguration: Default secrets, debug mode, open CORS
Best Practices Summary
- Always use HTTPS exclusively
- Keep access tokens short-lived (15 min), make refresh tokens revocable
- Use RBAC for coarse permissions, ABAC for granular policies
- Perform ownership checks on every endpoint that accesses specific resources
- Apply rate limiting at both IP and token level
- Validate input with schemas and whitelisting
- Never include sensitive data in JWT payloads
- Set security headers
- Return error messages without internal details
- Conduct regular security audits and penetration tests
FAQ: REST API Security
1. What is the difference between authentication and authorization?
2. What is RBAC?
3. What is ABAC?
4. What is Broken Object Level Authorization (BOLA)?
5. Why should access tokens be short-lived?
6. What is the difference between JWT and session cookies?
7. What is mass assignment and how do you prevent it?
role: admin and grant itself admin rights. Protection: use explicit field selection (whitelisting), DTOs containing only allowed fields, and validate all input.8. Why is CORS important for API security?
9. What is CSRF and how does it affect REST APIs?
10. Are JWT payloads encrypted?
11. What is the PKCE flow in OAuth 2.0?
12. How does rate limiting work for APIs?
13. Which HTTP status codes are relevant for authentication errors?
14. What is the principle of least privilege?
15. How do you revoke a JWT before it expires?
Next in the API Learning Path
The next article in the API learning path covers API Security Best Practices: protecting, securing, and operating APIs — the essential security measures for API operations following OWASP guidelines and industry best practices.
Sources and Further Resources
- https://owasp.org/API-Security/editions/2023/en/0x11-t10/
- https://datatracker.ietf.org/doc/html/rfc6749 (OAuth 2.0)
- https://datatracker.ietf.org/doc/html/rfc7519 (JWT)
- https://owasp.org/www-project-top-ten/
- https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html
Book Recommendations for API Development
API Development
Books about API design, REST, GraphQL, OpenAPI and API architecture
Designing Data-Intensive Applications von Martin Kleppmann
Bei Amazon ansehenAffiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.
API Design Patterns von JJ Geewax
Bei Amazon ansehenAffiliate-Link: Bei einem Kauf erhalten wir möglicherweise eine Provision.



