NextJS现代解法:SSR 鉴权逻辑 + 客户端注入模型

需求: 我要用SSR获取登录信息注入Client Comp

旧思路分析:
1. get请求,使用route handler
2. server fetch
3. 需要携带token,选用Authorization
4. token为了安全防XSS,存放在http-only cookie 无法使用js拿到cookie

矛盾产生了:http-only cookie无法取出来供server fetch 携带!2025-07-02

解决思路:
有三种通信抽象方法
1.2.「显式通信抽象」: REST API & Server Action
3. async function ≠ RSC,本身就可以抽象通信!

抽象落地:
1. async function for SSR

// Server-only: SSR or route handler 使用
import { cookies } from 'next/headers'
import { verifyJwt } from './jwt'
import { getUserByIdStrict } from '@/lib/db/user.dao'

export async function getUserFromCookie() {
  const token = cookies().get('token')?.value
  if (!token) return null

  const payload = verifyJwt(token)
  if (!payload) return null

  const user = await getUserByIdStrict(payload.sub, payload.tenantId)
  return user ?? null
}

 

2. CSR

// Client-only:如 CSR 页面的 useEffect 中调用
export async function getUserFromClient(): Promise<UserPublic | null> {
  const resp = await fetch('/api/account/checklogin', {
    credentials: 'include',
    cache: 'no-store',
  })

  if (!resp.ok) return null
  const data = await resp.json()
  return data.data
}

 

整体模型

SSR去鉴权,然后从服务端获得的safeUser 转到客户端组件userpublic,有效隔离敏感字段

客户端纯展示 + 状态注入

export default async function Page({ params }: { params: { tenant: string } }) {

    const { tenant: tenantName } = params

    const safeUser = await getUserFromCookie()
    if (!safeUser) {
        redirect(/${tenantName}/login)
    }
    return <AccountPageClient user={toUserPublic(safeUser)} />
}
"use client"
import { useAuthStore } from "@/store/authStore"
import { useEffect } from "react"
import { UserPublic } from "@/types/entities/User"

export default function AccountPageClient({ user }: { user: UserPublic }) {
    const setUser = useAuthStore(s => s.setUser)

    useEffect(() => {
        setUser(user)
    }, [user, setUser])


    return <>{user.username}</>
}

 

 

 

posted @ 2025-07-03 02:59  PEAR2020  阅读(55)  评论(0)    收藏  举报