-
-
Notifications
You must be signed in to change notification settings - Fork 768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: allow mounting oidc-provider to a next.js application #1229
Conversation
docs: update mounting docs to remove manual rewrites, include nextjs mounting example
Seeing the doc changes this is then a breaking change, isn't it? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In your original PR you wrote
I noticed the discovery paths were wrong, but also some generated paths like ones used by interactionFinished would be incorrect.
Would you mind simply demonstrating the issue first before continuing with this PR? I'm afraid you're doing breaking changes that I will not accept right now anyway. I'm being upfront about it so that you don't waste your time.
Presenting the issue in a project first would help to maybe add a nextjs run to the test suite as previously asked for here.
@@ -115,7 +116,7 @@ class Provider extends events.EventEmitter { | |||
|
|||
super(); | |||
|
|||
this.issuer = issuer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you removing the trailing slash in the issuer identifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In tests I was getting some failures because a route had double slashes, which didn't match the actual/expected value which had a single slash.
I thought it would be nice to ensure everything would always have a trailing slash removed. But I'm happy to put this back how it was and maybe update how the paths are generated elsewhere
Sure! I'll work backwards and demonstrate the issue. Either way I'm sure I could get something that is backwards compat working too. Is it specifically that it must be mounted under /oidc for specification reason or is it just any breaking change likely wont get shipped? |
Well the docs and then the tests demonstrated how to mount under a particular path, which is about the only reason i can imagine i would use a mounting strategy, to mount to an existing app under a unique path. So my conclusion of seeing existing tests changed is that you're introducing a breaking change, apologies if that's not the case, i just can't by looking at the change set. |
2feb48d
to
bc29267
Compare
lib/helpers/validate_dpop.js
Outdated
@@ -71,8 +71,9 @@ export default async (ctx, accessToken) => { | |||
} | |||
|
|||
{ | |||
const expected = new URL(ctx.oidc.urlFor(ctx.oidc.route)).href; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed to normalize the URL's scheme and hostname case independent, introduced 3 weeks ago in b72d668. You'd need to revert this change in your PR.
The provider is already mountable in a stable manner. If this is not working for next.js then please, provide a working minimal sample so that it may be included in the test suite and this issue resolved. The changes you're introducing in this PR are breaking the existing mounting interactions with some frameworks. |
bc29267
to
b5b9c7b
Compare
I've previously mounted node-oidc-provider on a NextJS application with success, without needing to modify the original oidc code. You only need to use the custom server implementation of NextJS. I made my custom server a Koa server, then serve all the oidc routes and fallback to nextjs. import { promisify } from 'node:util' // eslint-disable-line
import { parse } from 'node:url' // eslint-disable-line
import Koa from 'koa'
// import koaMount from 'koa-mount'
import next from 'next'
import helmet from 'helmet'
import { oidc } from './oidc/provider'
import { OidcRouter } from './oidc/routes'
import { PORT, IS_DEV, HOSTNAME } from './env'
// nextjs
const app = next({
dev: IS_DEV,
hostname: HOSTNAME,
port: PORT,
})
const nextHandler = app.getRequestHandler()
// koa
const koa = new Koa()
if (process.env.NODE_ENV === 'production') {
const directives = helmet.contentSecurityPolicy.getDefaultDirectives()
delete directives['form-action']
const pHelmet = promisify(helmet({
contentSecurityPolicy: {
useDefaults: false,
directives,
},
}))
koa.use(async (ctx, next) => {
await pHelmet(ctx.req, ctx.res)
return next() // eslint-disable-line
})
}
app.prepare().then(() => {
koa.use(OidcRouter(oidc).routes())
koa.use(async (ctx) => {
const oidcRegex = /^\/(\.well-known|auth|backchannel|device|session|token|jwks|request|reg|token|me)/
if (oidcRegex.test(ctx.path)) {
return oidc.callback()(ctx.req, ctx.res)
} else {
const parsedUrl = parse(ctx.url, true)
await nextHandler(ctx.req, ctx.res, parsedUrl)
}
})
koa.listen(PORT)
}) Then you can create your export const getServerSideProps = (async (ctx) => {
const { uid, prompt, params, session } = await oidc.interactionDetails(ctx.req, ctx.res)
const client = await oidc.Client.find(params.client_id as string)
const props = {
uid,
prompt,
params,
session,
client,
}
return {
props: process.env.NODE_ENV === 'production'
? props
: removeUndefined(props),
} Your custom routes go in './oidc/routes' and it's just a koa-router |
This has become stale, closing for now. |
Allow mounting of the oidc server to a next.js application.