Compare commits
4 Commits
2d3ce480c2
...
73048ba9d4
Author | SHA1 | Date |
---|---|---|
|
73048ba9d4 | |
|
ca3cada076 | |
|
362b6701a6 | |
|
f46705474f |
|
@ -117,6 +117,81 @@ const useSession = () => {
|
|||
|
||||
For more details on how to Popup Oauth Login see [example](https://github.com/divyam234/next-auth-hono-react)
|
||||
|
||||
## Middleware
|
||||
|
||||
You can separate this code into another file, say `auth.config.ts`:
|
||||
|
||||
```ts
|
||||
function getAuthConfig(c: Context): AuthConfig {
|
||||
return {
|
||||
secret: c.env.AUTH_SECRET,
|
||||
providers: [
|
||||
GitHub({
|
||||
clientId: c.env.GITHUB_ID,
|
||||
clientSecret: c.env.GITHUB_SECRET,
|
||||
}),
|
||||
],
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use the same config in `middleware.ts`
|
||||
|
||||
```ts
|
||||
import { getAuthConfig } from '@/auth.config'
|
||||
import { getAuthUser, initAuthConfig } from '@hono/auth-js'
|
||||
import { Hono } from 'hono'
|
||||
import { handle } from 'hono/vercel'
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
// shared config
|
||||
app.use('*', initAuthConfig(getAuthConfig))
|
||||
|
||||
app.all('*', async (c) => {
|
||||
// Retrieve the user & session
|
||||
const authUser = await getAuthUser(c)
|
||||
|
||||
const pathname = new URL(c.req.url).pathname
|
||||
const isAuthenticated = !!authUser?.session
|
||||
|
||||
// Specific to Auth.js (may vary if customized)
|
||||
const isApiAuthRoute = pathname.startsWith('/api/auth')
|
||||
|
||||
const isPublicRoute = ['/'].includes(pathname)
|
||||
const isAuthRoute = ['/sign-in'].includes(pathname)
|
||||
|
||||
if (isApiAuthRoute) return NextResponse.next()
|
||||
|
||||
if (isAuthRoute) {
|
||||
if (isAuthenticated) {
|
||||
return Response.redirect(new URL('/protected', c.req.url))
|
||||
}
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
if (!isAuthenticated && !isPublicRoute) {
|
||||
return Response.redirect(new URL('/sign-in', c.req.url))
|
||||
}
|
||||
|
||||
return NextResponse.next()
|
||||
})
|
||||
|
||||
export default handle(app)
|
||||
|
||||
export const config = {
|
||||
matcher: ['/((?!.+\\.[\\w]+$|_next).*)', '/', '/(api|trpc)(.*)'],
|
||||
}
|
||||
```
|
||||
|
||||
Middleware setup repo: https://github.com/mohit4bug/nextjs-hono-authjs
|
||||
|
||||
## Author
|
||||
|
||||
Divyam <https://github.com/divyam234>
|
||||
|
||||
## Contributors
|
||||
|
||||
- Mohit <https://github.com/mohit4bug>
|
||||
- Updated the README.md to include additional details about using middleware.
|
|
@ -1,5 +1,11 @@
|
|||
# @hono/otel
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1113](https://github.com/honojs/middleware/pull/1113) [`362b6701a6ee2843a51c1dfd5877a6164b7474fb`](https://github.com/honojs/middleware/commit/362b6701a6ee2843a51c1dfd5877a6164b7474fb) Thanks [@milohansen](https://github.com/milohansen)! - Use `req.routePath` to augment spans with the path that handled the request.
|
||||
|
||||
## 0.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@hono/otel",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"description": "OpenTelemetry middleware for Hono",
|
||||
"type": "module",
|
||||
"module": "dist/index.js",
|
||||
|
|
|
@ -26,6 +26,13 @@ describe('OpenTelemetry middleware', () => {
|
|||
throw new Error('error message')
|
||||
})
|
||||
|
||||
const subapp = new Hono()
|
||||
subapp.get('/hello', (c) => c.text('Hello from subapp!'))
|
||||
subapp.get('*', (c) => c.text('Fallthrough'))
|
||||
|
||||
// mount subapp
|
||||
app.route('/subapp', subapp)
|
||||
|
||||
it('Should make a span', async () => {
|
||||
memoryExporter.reset()
|
||||
const response = await app.request('http://localhost/foo')
|
||||
|
@ -71,4 +78,13 @@ describe('OpenTelemetry middleware', () => {
|
|||
expect(span.name).toBe('GET /foo')
|
||||
expect(span.attributes[ATTR_HTTP_ROUTE]).toBe('/foo')
|
||||
})
|
||||
|
||||
// Issue #1112
|
||||
it('Should set the correct span name for subapp', async () => {
|
||||
memoryExporter.reset()
|
||||
await app.request('http://localhost/subapp/hello')
|
||||
const spans = memoryExporter.getFinishedSpans()
|
||||
const [span] = spans
|
||||
expect(span.name).toBe('GET /subapp/hello')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -15,11 +15,13 @@ import metadata from '../package.json' with { type: 'json'}
|
|||
const PACKAGE_NAME = metadata.name
|
||||
const PACKAGE_VERSION = metadata.version
|
||||
|
||||
export type OtelOptions = {
|
||||
augmentSpan?: false;
|
||||
export type OtelOptions =
|
||||
| {
|
||||
augmentSpan?: false
|
||||
tracerProvider?: TracerProvider
|
||||
} | {
|
||||
augmentSpan: true;
|
||||
}
|
||||
| {
|
||||
augmentSpan: true
|
||||
}
|
||||
|
||||
export const otel = <E extends Env = any, P extends string = any, I extends Input = {}>(
|
||||
|
@ -30,9 +32,9 @@ export const otel = <E extends Env = any, P extends string = any, I extends Inpu
|
|||
const result = await next()
|
||||
const span = trace.getActiveSpan()
|
||||
if (span != null) {
|
||||
const route = c.req.matchedRoutes[c.req.matchedRoutes.length - 1]
|
||||
span.setAttribute(ATTR_HTTP_ROUTE, route.path)
|
||||
span.updateName(`${c.req.method} ${route.path}`)
|
||||
const routePath = c.req.routePath
|
||||
span.setAttribute(ATTR_HTTP_ROUTE, routePath)
|
||||
span.updateName(`${c.req.method} ${routePath}`)
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
@ -40,15 +42,15 @@ export const otel = <E extends Env = any, P extends string = any, I extends Inpu
|
|||
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider()
|
||||
const tracer = tracerProvider.getTracer(PACKAGE_NAME, PACKAGE_VERSION)
|
||||
return createMiddleware<E, P, I>(async (c, next) => {
|
||||
const route = c.req.matchedRoutes[c.req.matchedRoutes.length - 1]
|
||||
const routePath = c.req.routePath
|
||||
await tracer.startActiveSpan(
|
||||
`${c.req.method} ${route.path}`,
|
||||
`${c.req.method} ${c.req.routePath}`,
|
||||
{
|
||||
kind: SpanKind.SERVER,
|
||||
attributes: {
|
||||
[ATTR_HTTP_REQUEST_METHOD]: c.req.method,
|
||||
[ATTR_URL_FULL]: c.req.url,
|
||||
[ATTR_HTTP_ROUTE]: route.path,
|
||||
[ATTR_HTTP_ROUTE]: routePath,
|
||||
},
|
||||
},
|
||||
async (span) => {
|
||||
|
@ -57,6 +59,10 @@ export const otel = <E extends Env = any, P extends string = any, I extends Inpu
|
|||
}
|
||||
try {
|
||||
await next()
|
||||
// Update the span name and route path now that we have the response
|
||||
// because the route path may have changed
|
||||
span.updateName(`${c.req.method} ${c.req.routePath}`)
|
||||
span.setAttribute(ATTR_HTTP_ROUTE, c.req.routePath)
|
||||
span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, c.res.status)
|
||||
for (const [name, value] of c.res.headers.entries()) {
|
||||
span.setAttribute(ATTR_HTTP_RESPONSE_HEADER(name), value)
|
||||
|
|
Loading…
Reference in New Issue