AMP • TR
API güvenliği, OAuth2, JWT, rate limiting, API gateway ve GraphQL security best practices 2025.
API'ler modern uygulamaların bel kemiği. Güvenlik açıkları kritik risk oluşturuyor. Kapsamlı API güvenlik rehberi.
// Authorization Code Flow
app.get('/auth', (req, res) => {
const authUrl = `https://oauth.provider.com/authorize?
client_id=${CLIENT_ID}&
redirect_uri=${REDIRECT_URI}&
response_type=code&
scope=read write&
state=${generateState()}`;
res.redirect(authUrl);
});
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
// Verify state (CSRF protection)
if (!verifyState(state)) {
return res.status(401).send('Invalid state');
}
// Exchange code for token
const tokens = await exchangeCodeForToken(code);
// Store tokens securely
storeTokens(tokens);
res.redirect('/dashboard');
});
const jwt = require('jsonwebtoken');
// Generate JWT
function generateToken(user) {
return jwt.sign(
{
sub: user.id,
email: user.email,
role: user.role
},
process.env.JWT_SECRET,
{
expiresIn: '1h',
issuer: 'api.example.com',
audience: 'example.com'
}
);
}
// Verify JWT
function verifyToken(token) {
try {
return jwt.verify(token, process.env.JWT_SECRET, {
issuer: 'api.example.com',
audience: 'example.com'
});
} catch (error) {
throw new Error('Invalid token');
}
}
// Middleware
function authenticateJWT(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'No token provided' });
}
try {
const decoded = verifyToken(token);
req.user = decoded;
next();
} catch (error) {
return res.status(403).json({ error: 'Invalid token' });
}
}
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const redis = require('redis');
const client = redis.createClient();
// Global rate limit
const globalLimiter = rateLimit({
store: new RedisStore({ client }),
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // 100 requests per window
message: 'Too many requests, please try again later'
});
// Endpoint-specific rate limit
const strictLimiter = rateLimit({
store: new RedisStore({ client }),
windowMs: 60 * 1000, // 1 minute
max: 5, // 5 requests per minute
message: 'Rate limit exceeded'
});
// Apply
app.use('/api/', globalLimiter);
app.post('/api/login', strictLimiter, loginHandler);
const Joi = require('joi');
// Validation schema
const userSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().min(8).pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/).required(),
age: Joi.number().integer().min(18).max(120),
username: Joi.string().alphanum().min(3).max(30).required()
});
// Validate middleware
function validateUser(req, res, next) {
const { error, value } = userSchema.validate(req.body);
if (error) {
return res.status(400).json({
error: 'Validation failed',
details: error.details.map(d => d.message)
});
}
req.validatedData = value;
next();
}
app.post('/api/users', validateUser, createUser);
# Kong API Gateway configuration
services:
- name: user-service
url: http://user-service:8080
plugins:
# Authentication
- name: jwt
config:
secret_is_base64: false
key_claim_name: kid
# Rate limiting
- name: rate-limiting
config:
minute: 100
hour: 1000
policy: redis
# IP restriction
- name: ip-restriction
config:
whitelist:
- 10.0.0.0/8
- 172.16.0.0/12
# CORS
- name: cors
config:
origins:
- https://app.example.com
credentials: true
max_age: 3600
const { ApolloServer } = require('apollo-server');
const depthLimit = require('graphql-depth-limit');
const { createComplexityLimitRule } = require('graphql-validation-complexity');
const server = new ApolloServer({
typeDefs,
resolvers,
// Query depth limiting
validationRules: [
depthLimit(10), // Max query depth: 10
createComplexityLimitRule(1000) // Max complexity: 1000
],
// Disable introspection in production
introspection: process.env.NODE_ENV !== 'production',
playground: process.env.NODE_ENV !== 'production',
// Context with auth
context: ({ req }) => {
const token = req.headers.authorization;
const user = verifyToken(token);
return { user };
},
// Error handling
formatError: (error) => {
// Don't expose internal errors
if (error.message.startsWith('Database')) {
return new Error('Internal server error');
}
return error;
}
});
# OWASP ZAP API scan
zap-cli quick-scan --spider -r https://api.example.com
# Postman security tests
pm.test("No sensitive data in response", function () {
pm.expect(pm.response.text()).to.not.include("password");
pm.expect(pm.response.text()).to.not.include("secret");
});
pm.test("Proper auth required", function () {
pm.sendRequest({
url: pm.environment.get("API_URL") + "/admin",
method: "GET"
}, function (err, res) {
pm.expect(res.code).to.equal(401);
});
});
✅ Authentication:
✅ Authorization:
✅ Data:
✅ Rate Limiting:
✅ Monitoring:
API security danışmanlığı: iletisim@cesayazilim.com 🔐