middleware icon indicating copy to clipboard operation
middleware copied to clipboard

oidc-auth don't work behind proxy. Incorrect redirect on success

Open SergKam opened this issue 6 months ago • 2 comments

Which middleware has the bug?

@hono/oidc-auth

What version of the middleware?

1.6.1

What version of Hono are you using?

4.7.11

What runtime/platform is your app running on? (with version if possible)

aws lambda

What steps can reproduce the bug?

Running in AWS Lambda using functionUrl (but it can be any loadbalancer or reverse proxy). Use AWS Cognito to log in.

What is the expected behavior?

Redirects to the starting page of my domain

What do you see instead?

Login successful, but then redirects the browser to the wrong internal aws lambda URL

Additional information

The middleware sets the "continue" cookie to the request URL. In case of any reverse proxy, with AWS Lambda, it will be the long internal Lambda DNS name and not the public DNS name of the service.
Means the cookie will not work because it set for external DNS name. The problem is here
https://github.com/honojs/middleware/blob/main/packages/oidc-auth/src/index.ts#L465 It should be configurable, similar to OIDC_REDIRECT_URI or use OIDC_REDIRECT_URI or OIDC_COOKIE_DOMAIN.

The ugly workaround I have to do is fix AWS lambda event payload before it enters Hono:

// Custom handler that fixes the host/URL before passing to Hono
export const handler = async (
	event: Record<string, unknown>,
	context: Context,
) => {
	// Log original request details
	const headers = event.headers as Record<string, string> | undefined;
	const requestContext = event.requestContext as
		| Record<string, unknown>
		| undefined;
	console.log("Original event:", JSON.stringify(event, null, 2));

	// Replace the host header and requestContext.domainName with CloudFront domain
	if (process.env.OIDC_COOKIE_DOMAIN) {
		// Update host headers
		if (headers) {
			if (headers.host) {
				headers.host = process.env.OIDC_COOKIE_DOMAIN;
			}
			if (headers.Host) {
				headers.Host = process.env.OIDC_COOKIE_DOMAIN;
			}
		}

		// Update requestContext.domainName (this is what OIDC middleware uses)
		if (requestContext) {
			requestContext.domainName = process.env.OIDC_COOKIE_DOMAIN;
		}
	}

	// Pass the modified event to Hono's handler
	// biome-ignore lint/suspicious/noExplicitAny: Lambda event typing is complex, using any for flexibility
	return handle(app)(event as any, context);
};

SergKam avatar Jun 11 '25 09:06 SergKam

@SergKam Thank you for the issue!

Hi @hnw, can you handle this issue?

yusukebe avatar Jun 11 '25 10:06 yusukebe

Hi @SergKam,

Thank you for creating such a detailed and helpful issue report, including a clear description of the problem and a workaround. I sincerely appreciate it.

You are absolutely right. This is a classic issue for applications running behind a reverse proxy, and our current implementation doesn't handle this use case gracefully. Your analysis of how the continue cookie's URL is generated is spot on.

I agree with your proposed solution. To address this, I will introduce a new environment variable: OIDC_AUTH_EXTERNAL_URL.

This variable should be set to the full, public-facing base URL of your application, including the protocol and any path prefixes.

Usage Examples:

  • If your app is at the root of a subdomain: OIDC_AUTH_EXTERNAL_URL="https://app.example.com"
  • If your app is served from a sub-path: OIDC_AUTH_EXTERNAL_URL="https://example.com/myapp"
  • If this variable is not set, the middleware will fall back to the existing behavior to ensure backward compatibility.

I will start working on this change. I will post updates on our progress here.

Thanks again for your valuable contribution to improving oidc-auth!

hnw avatar Jun 15 '25 11:06 hnw