koajs / koa

Expressive middleware for node.js using ES2017 async functions
https://koajs.com
MIT License
35.24k stars 3.23k forks source link

Can't access peer/client certificate with Koa #1744

Closed Bointz closed 1 year ago

Bointz commented 1 year ago

Hi,

I read in another (closed) thread that it's possible to access the client certificate using Koa. I tried the solution in the other thread (below) however it doesn't work as I get the following error. If I can't get a solution I'll need to switch the Express as it's easy to access the peer certificate using the getPeerCertificate() call.

No overload matches this call. Overload 1 of 4, '(name: string, path: string | RegExp, ...middleware: IMiddleware<any, {}>[]): Router<any, {}>', gave the following error. Argument of type '(ctx: IKoaContext, { const: c, console, log }: { const?: IKoaContext | undefined; console: any; log: any; }) => any' is not assignable to parameter of type 'string | RegExp'. Overload 2 of 4, '(path: string | RegExp | (string | RegExp)[], ...middleware: IMiddleware<any, {}>[]): Router<any, {}>', gave the following error. Argument of type '(ctx: IKoaContext, { const: c, console, log }: { const?: IKoaContext | undefined; console: any; log: any; }) => any' is not assignable to parameter of type 'IMiddleware<any, {}>'. Types of parameters 'ctx' and 'context' are incompatible. Type 'ParameterizedContext<any, IRouterParamContext<any, {}>, any>' is not assignable to type 'IKoaContext'. Types of property 'socket' are incompatible. Type 'Socket' is missing the following properties from type 'TLSSocket': authorized, authorizationError, encrypted, alpnProtocol, and 18 more. Overload 3 of 4, '(name: string, path: string | RegExp, middleware: Middleware<unknown, unknown, any>, routeHandler: IMiddleware<any, {}>): Router<any, {}>', gave the following error. Argument of type '(ctx: IKoaContext, { const: c, console, log }: { const?: IKoaContext | undefined; console: any; log: any; }) => any' is not assignable to parameter of type 'string | RegExp'.ts(2769)

Welcome @ilanl, I believe that the problem is from @types/koa. So you need to do something like that:

// the 1st solution: access from socket inside the koa context.
import * as Koa from 'koa'
import { TLSSocket } from 'tls'

const app = new Koa()

// the current Koa types use Socket from 'net' module 
// where 'getPeerCertificate' from 'tls' module.
interface IKoaContext extends Koa.Context {
  socket: TLSSocket
}

function middleware (ctx: IKoaContext, next: Koa.Next) {
  ctx.socket.getPeerCertificate()
}

// the 2nd solution: access from raw request inside the koa context or both.
import * as Koa from 'koa'
import { IncomingMessage } from 'http'
import { TLSSocket } from 'tls'

const app = new Koa()

interface RawRequest extends IncomingMessage {
  socket: TLSSocket
}

interface IKoaContext extends Koa.Context {
  socket: TLSSocket, // line 1
  req: RawRequest // line 2
}

function middleware (ctx: IKoaContext, next: Koa.Next) {
  ctx.socket.getPeerCertificate() // given from line 1
  ctx.req.socket.getPeerCertificate() // given from line 2
}

Originally posted by @3imed-jaberi in https://github.com/koajs/koa/issues/1519#issuecomment-769231704

iwanofski commented 1 year ago

As this has been open and stale for a while I'm going to close it.