cannot get `context.session.$publicData` with `passportAuth` and app router
- Dominant language
- TypeScript
- Stars
- 14.1k
- Forks
- 803
- PR merge metrics
- No merged PRs in 30d
Description
### What is the problem?
I'm trying to migrate from `page` to `app`.
Our application uses `passport -google-oauth20` to authenticate users. But even though users have signed in, they can't be authenticated by `useAuthenticatedBlitzContext`, and redirect to login page.
It seems that there is no session data in `BlitzContext`.
Session has been created.(in Client Component, `useSession` returns session data correctly)
How can I do about this?
### Paste all your error logs here:
It seems that there is no error logs in both client and server.
### Paste all relevant code snippets here:
app/blitz-client.ts
```typescript
"use client"
import { AuthClientPlugin } from "@blitzjs/auth"
import { setupBlitzClient } from "@blitzjs/next"
import { BlitzRpcPlugin } from "@blitzjs/rpc"
export const authConfig = {
cookiePrefix: "my-cookie",
}
export const { withBlitz, BlitzProvider, useSession, useAuthenticatedSession } = setupBlitzClient({
plugins: [AuthClientPlugin(authConfig), BlitzRpcPlugin({})],
})
```
/app/blitz-server.ts
```typescript
import { setupBlitzServer } from "@blitzjs/next"
import { AuthServerPlugin, PrismaStorage } from "@blitzjs/auth"
import { simpleRolesIsAuthorized } from "@blitzjs/auth"
import { BlitzLogger } from "blitz"
import db from "db"
import { authConfig } from "./blitz-client"
import { RpcServerPlugin } from "@blitzjs/rpc"
export const { gSSP, gSP, useAuthenticatedBlitzContext, getBlitzContext, api, invoke } =
setupBlitzServer({
plugins: [
AuthServerPlugin({
...authConfig,
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
RpcServerPlugin({}),
],
logger: BlitzLogger({}),
})
```
/app/layout.tsx
```typescript
"use client"
import React from "react"
import { BlitzProvider } from "app/blitz-client"
import "./globals.css"
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
Karabina
{children}
)
}
```
/app/page.tsx
```typescript
import Link from "next/link"
export default function Page() {
Sign in with Google
}
```
/src/pages/api/auth/[...auth].ts
```typescript
import { passportAuth } from "@blitzjs/auth"
import { api } from "app/blitz-server"
import db from "db"
import { Strategy as GoogleStrategy } from "passport-google-oauth20"
import * as process from "process"
export default api(
passportAuth({
successRedirectUrl: "/",
errorRedirectUrl: "/",
secureProxy: true,
strategies: [
{
strategy: new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: process.env.GOOGLE_CALLBACK,
scope: ["email"],
},
async function (accessToken, refreshToken, profile, done) {
const email = profile.emails && profile.emails[0]?.value
if (!email) {
return done(new Error("Google response doesn't have email."))
}
const userIdp = await db.userIdp.upsert({
where: {
provider_providerId: { provider: profile.provider, providerId: profile.id },
},
create: {
provider: profile.provider,
providerId: profile.id,
},
update: { providerId: profile.id },
})
const user = await db.user.upsert({
where: { userIdpId: userIdp.id },
create: {
email,
name: email,
userIdpId: userIdp.id,
},
update: { email },
})
const publicData = {
userId: user.id,
roles: [user.role],
source: userIdp.provider,
}
done(undefined, { publicData })
}
),
},
],
})
)
```
/app/secure/page.tsx
```typescript
import { getBlitzContext, useAuthenticatedBlitzContext } from "app/blitz-server"
export default async function Page() {
const ctx = await getBlitzContext()
console.log(ctx.session.$publicData) // => { userId: null }
await useAuthenticatedBlitzContext({
redirectTo: "/auth/login",
role: ["USER"],
redirectAuthenticatedTo: "/",
})
return
}
```
### What are detailed steps to reproduce this?
1. click the `Sign in with Google` in `/` with no authentication
2. authenticate and permit to access in Google website
3. redirect back to `/` from Google website
4. go to `/secure`
5. redirect to `/auth/login` by `useAuthenticatedBlitzContext` <= this is the problem.
### Run `blitz -v` and paste the output here:
```
> blitz -v
Blitz version: 2.0.0-beta.20 (global)
Blitz version: 2.0.0-beta.32 (local)
macOS Monterey | darwin-arm64 | Node: v16.16.0
Package manager: npm
System:
OS: macOS 12.5.1
CPU: (8) arm64 Apple M1
Memory: 84.44 MB / 16.00 GB
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.16.0 - ~/.anyenv/envs/nodenv/versions/16.16.0/bin/node
Yarn: 3.6.2 - ~/.volta/bin/yarn
npm: 8.15.1 - ~/.anyenv/envs/nodenv/versions/16.16.0/bin/npm
npmPackages:
@blitzjs/auth: 2.0.0-beta.32 => 2.0.0-beta.32
@blitzjs/next: 2.0.0-beta.32 => 2.0.0-beta.32
@blitzjs/rpc: 2.0.0-beta.32 => 2.0.0-beta.32
@prisma/client: ^5.2.0 => 5.2.0
blitz: 2.0.0-beta.32 => 2.0.0-beta.32
next: 13.4.19 => 13.4.19
prisma: ^5.2.0 => 5.2.0
react: 18.2.0 => 18.2.0
react-dom: 18.2.0 => 18.2.0
typescript: ^4.8.4 => 4.9.5
```
### Please include below any other applicable logs and screenshots that show your problem:
_No response_
Contributor guide
Research direction
Start by reproducing the listed flow with app/blitz-client.ts, app/blitz-server.ts, src/pages/api/auth/[...auth].ts, and app/secure/page.tsx, focusing on passportAuth and getBlitzContext. Trace why the session differs between useSession and ctx.session.$publicData; done means Google authentication populates the public session and /secure no longer redirects authenticated users to /auth/login.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nextjs, typescript
- Domain
- authentication, backend-api-design
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100