feat(auth): add api key authentication
Implement API key authentication by introducing a new auth module. Update configuration and .env.example to support API key setup, and add authorization checks in the server endpoints.
This commit is contained in:
@@ -1,2 +1,3 @@
|
||||
PORT=11434
|
||||
VERBOSE=false
|
||||
VERBOSE=false
|
||||
API_KEY=MY0P3NA1K3Y
|
||||
38
src/auth.ts
Normal file
38
src/auth.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @fileoverview This file contains the authentication logic for the server.
|
||||
*/
|
||||
import http from 'http';
|
||||
import { config } from './config';
|
||||
|
||||
/**
|
||||
* Checks for API key authentication.
|
||||
* @param req - The HTTP incoming message object.
|
||||
* @param res - The HTTP server response object.
|
||||
* @returns True if the request is authorized, false otherwise.
|
||||
*/
|
||||
export function isAuthorized(
|
||||
req: http.IncomingMessage,
|
||||
res: http.ServerResponse,
|
||||
): boolean {
|
||||
if (!config.API_KEY) {
|
||||
return true; // No key configured, public access.
|
||||
}
|
||||
|
||||
const authHeader = req.headers.authorization;
|
||||
if (!authHeader) {
|
||||
res.writeHead(401, { 'Content-Type': 'application/json' });
|
||||
res.end(
|
||||
JSON.stringify({ error: { message: 'Missing Authorization header' } }),
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
const token = authHeader.split(' ')[1];
|
||||
if (token !== config.API_KEY) {
|
||||
res.writeHead(401, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ error: { message: 'Invalid API key' } }));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -23,4 +23,10 @@ export const config = {
|
||||
* @type {boolean}
|
||||
*/
|
||||
VERBOSE: Boolean(process.env.VERBOSE ?? true),
|
||||
/**
|
||||
* The API key for securing the server.
|
||||
* If not set, the server will be public.
|
||||
* @type {string | undefined}
|
||||
*/
|
||||
API_KEY: process.env.API_KEY,
|
||||
};
|
||||
@@ -8,6 +8,7 @@ import { listModels, sendChat, sendChatStream } from './chatwrapper';
|
||||
import { mapRequest, mapResponse, mapStreamChunk } from './mapper.js';
|
||||
import { RequestBody, GeminiResponse, GeminiStreamChunk, Part } from './types';
|
||||
import { config } from './config';
|
||||
import { isAuthorized } from './auth';
|
||||
|
||||
// ==================================================================
|
||||
// Server Configuration
|
||||
@@ -97,6 +98,10 @@ http
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAuthorized(req, res)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Route for listing available models.
|
||||
if (pathname === '/v1/models' || pathname === '/models') {
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
|
||||
Reference in New Issue
Block a user