blitz-js / blitz-js/blitz

cannot get `context.session.$publicData` with `passportAuth` and app router

Open
#4,213 0 comments 0 reactions 0 assignees View on GitHub
kind/bug status/triage
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

Secured Content

}
```

### 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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.