跳到主要内容

NextAuth

  • nextauthjs/next-auth
    • ISC, TS
  • 回调 /api/auth/callback/<NAME>
  • Provider
    • Gitlab
      • 回调要完整,127.0.0.1 要额外加
      • 可以配置多个回调
    • Github
      • 回调配前缀,默认支持 127.0.0.1
      • 只能配置一个回调
警告
envfor
NEXTAUTH_URL
NEXTAUTH_SECRET生产环境必须
NEXTAUTH_URL_INTERNAL默认 NEXTAUTH_URL
  • AUTH_TRUST_HOST || VERCEL
    • 用于 detectHost
警告
// 内部全局上下文
const __NEXTAUTH: NextAuthClientConfig = {
baseUrl: parseUrl(process.env.NEXTAUTH_URL ?? process.env.VERCEL_URL).origin,
basePath: parseUrl(process.env.NEXTAUTH_URL).path,
baseUrlServer: parseUrl(process.env.NEXTAUTH_URL_INTERNAL ?? process.env.NEXTAUTH_URL ?? process.env.VERCEL_URL)
.origin,
basePathServer: parseUrl(process.env.NEXTAUTH_URL_INTERNAL ?? process.env.NEXTAUTH_URL).path,
_lastSync: 0,
_session: undefined,
_getSession: () => {},
};

// profile 转 account 逻辑
const getProfile = {
profile,
account: {
provider: provider.id,
type: provider.type,
providerAccountId: profile.id.toString(),
...tokens,
},
OAuthProfile: profile,
};

export const defaultCallbacks: CallbacksOptions = {
signIn() {
// 是否允许登录
// 可以返回 字符串做 redirect
return true;
},
redirect({ url, baseUrl }) {
if (url.startsWith('/')) return `${baseUrl}${url}`;
else if (new URL(url).origin === baseUrl) return url;
return baseUrl;
},
session({ session }) {
return session;
},
// jwt session
jwt({ token }) {
return token;
},
};
  • callbacks - https://next-auth.js.org/configuration/callbacks
    • signIn - 可以拒绝用户登录
    • redirect - 构造跳转 URL
    • jwt
      • 触发 /api/auth/signin, /api/auth/session, getSession(), getServerSession(), useSession()
      • 第一次创建时有的参数 user, account, profile, isNewUser
      • 之后都只有 token
      • token 基础属性 - name, email, sub, iat, exp, jti
    • session
      • 触发 getSession(), useSession(), /api/auth/session
  • tokens:TokenSet
    • 包含 access_token
  • createState - state
    • maxAge: 900 - 15m
  • 会在 sessionMaxAge 更新 session 有效期
import { generators } from 'openid-client';
// 生成 state
const state = generators.state();

数据模型

  • User -1-*-> Account
  • User -1-*-> Session
  • VerificationToken

Adapter

  • 登录
    • createUser
    • getUser
    • getUserByEmail
    • getUserByAccount
    • linkAccount
    • createSession
    • getSessionAndUser
    • updateSession
    • deleteSession
    • updateUser
  • 邮箱/无密码登录
    • createVerificationToken
    • useVerificationToken
  • 目前没用到
    • deleteUser
    • unlinkAccount

REST API

methodurlnote
GET/api/auth/signin内置登录页
GET/api/auth/signout内置登出页
POST/api/auth/signout退出登录 - CSRF
GET/api/auth/csrf获取 CSRF
GET/api/auth/session
GET/api/auth/providers
POST/api/auth/signin/:provider开始登录流程
GET/api/auth/callback/:providerOAuth 回调
POST/api/auth/callback/:provider账号密码登录 - CSRF

FAQ

刷新 JWT

  • 通过自定义 SignIn 来刷新
  • #4229 How to manually trigger next-auth to refresh the JWT?

CORS

  • HTTP Only
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
getCookie('next-auth.session-token');