大家都知道 Next
有个 NextAuth
非常好用,其实 Nuxt
也有配套的 Auth Module
而且 NuxtAuth
还依赖于 NextAuth
,这为 Nuxt
生态提供了非常多可靠性和便利性。
NextAuth
里能用的,在 NuxtAuth
里同样支持
并且还针对Nuxt 提供了特定功能,比如登录、注销、身份验证中间件和插件等
使用 NuxtAuth 时需要注意,它包装了 next-auth@4.21.1
,因为更高的版本中更改了包导出。
所以使用时,安装指定版本就可以了。
这里我先以 Github登录 为例演示其用法
本系列在博客站上会持续更新,直到覆盖NuxtAuth的所有用法
我在一个 layer
中演示其使用方法,因为这部分功能相对独立,使用的地方继承就行。
新建项目
npx nuxi init -t layer zz-auth-layer
然后来到项目根目录下,安装依赖
注:这里有两种 Provider
可选,一个是 authjs(next-auth)
,一个是 local
,所谓 local
就是你已经自己写好了一套登录逻辑,他可以帮你接管一下。
pnpm exec nuxi module add sidebase-auth
// 因为我们使用github登录,所以要安装这个包
pnpm add next-auth@4.21.1
给此项目开启 Nuxt4
的特性,Nuxt4
的目录结构更合理,更适合拓展。
export default defineNuxtConfig({
future: {
compatibilityVersion: 4
},
})
然后把根目录下的内容改造成 v4 的结构
.
├── .editorconfig
├── .env
├── .gitignore
├── .npmignore
├── .npmrc
├── .nuxtrc
├── README.md
├── app
│ ├── app.config.ts
│ ├── app.vue
│ └── components
│ └── AuthView.vue
├── nuxt.config.ts
├── package.json
├── pnpm-lock.yaml
├── server
│ ├── api
│ │ └── auth
│ └── tsconfig.json
└── tsconfig.json
组件 AuthView
里什么也没有,随便写点东西就行
然后再把刚才安装的 nuxt-auth
配置一下。这里的配置内容,来源于官方文档。
export default defineNuxtConfig({
future: {
compatibilityVersion: 4
},
auth: {
isEnabled: true,
disableServerSideAuth: false,
originEnvKey: 'NUXT_AUTH_ORIGIN',
// baseURL: 'http://localhost:3000/api/auth',
provider: {
type: 'authjs',
trustHost: false,
defaultProvider: 'github',
addDefaultCallbackUrl: true,
},
sessionRefresh: {
enablePeriodically: 1000 * 60 * 5, // 5 分钟刷新一次
enableOnWindowFocus: true,
}
},
})
如果你此时是按照官方文档一步步的来的,那这里的 provider
就是后面配上的
然后在 app.config.ts
里增加一些信息
export default defineAppConfig({
authLayer: {
name: 'Hello from Auth layer (playground)',
enabled: true,
}
})
当这个 auth-layer
层被其他模块 extend
时,这个 authLayer
对象就会被合并过去
所以也可以直接在其他模块中使用 useAppConfig().authLayer?.enabled
来判断当前是否开启了鉴权的层
然后再来配置环境变量
刚才已经配置了一个 originEnvKey
为 NUXT_AUTH_ORIGIN
,所以需要在 .env 中增加这个环境变量
NUXT_AUTH_ORIGIN=http://localhost:3000/api/auth
此时配置的这个路径,需要我们自己定义出来,所以先新增这个接口server/api/auth/[...].ts
这个接口是一个 NuxtAuthHandler
,是从 NextAuthHandler
基础上改编来的,我们需要在这个 Handler
中定义我们的 Provider
,也就是 Github
import GithubProvider from 'next-auth/providers/github'
import { NuxtAuthHandler } from '#auth'
export default NuxtAuthHandler({
// A secret string you define, to ensure correct encryption
secret: 'your-secret-here',
providers: [
// @ts-expect-error Use .default here for it to work during SSR.
GithubProvider.default({
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
})
]
})
定义好后需要再定义一下 secret
,以及Github
需要的 id 和 secret
先在 nuxt.config.ts
中定义 runtimeConfig
runtimeConfig: {
authSecret: 'your_secret',
authOrigin: 'your_secret',
githubClientId: 'your_secret',
githubClientSecret: 'your_secret',
}
runtimeConfig
里的 authSecret
会被 .env
里的 NUXT_AUTH_SECRET
所覆盖
所以我们把真实的 authSecret
写在 .env
,然后在 git
中忽略即可
此时已经定义好了需要的四个环境变量
NUXT_AUTH_ORIGIN=http://localhost:3000/api/auth
NUXT_AUTH_SECTRET=123131231231
NUXT_GITHUB_CLIENT_ID=xxxxx
NUXT_GITHUB_CLIENT_SECRET=xxxxxx
但是 Github 的 id 和 secret 还需要自己去申请
先打开 Github ,登录后,点击头像 -> Settings -> 左侧菜单拉到最下边的 developer settings -> OAuth Apps -> New OAuth App
然后填写如下表单即可

因为请求 Github
之后,Github
需要再跳过来,需要 callback URL
需要填你本地项目的一个页面地址
等待上线后,再把此处的OAuth App
以及 .env
(看部署方式而定) 里配置的本地路径改为线上路径
注册后就会给你一个 id 和 secret ,把它写在 .env
里
配置好后,我们就可以使用 NuxtAuth
提供的 composable
来管理鉴权的逻辑了
为什么不在根目录下直接写,而是在 .playground
中写呢?
因为根目录下相当于一个独立的npm包,是要给其他项目使用的,而.playground
就相当于是模拟了其他项目
所以在 layer
部分,只需要完成通用的配置、页面、接口即可,具体使用时都在 .playground
里操作
playground
里已经写好了 extends: ['..']
,所以我们直接新建一个页面来测试一下如何使用 Github
登录
const {
status,
data,
lastRefreshedAt,
getCsrfToken,
getProviders,
getSession,
signIn,
signOut
} = useAuth()
<button @click="signIn('github')"> 使用 Github 登录</button>
当点击按钮时,就会跳转到 Github
,授权登录后就能拿到 Github
提供的用户信息
在此之后的逻辑就和Github无关了
NuxtAuth
会帮我们做一整套的逻辑,我们只需要拿到用户信息后,和自行注册的用户做一个关联即可
status
表示当前登录状态
data
表示当前会话中的数据,这个 sessionData
也可以在 NuxtAuthHandler
的 callback
中插入一些用户信息
登出时,使用 signOut
即可
如果是使用自己写的逻辑,也就是 local Provider
,还可以配置 refreshToken 的接口等等
部署时,只需要注意一下 .env
文件,因为 Nuxt 打包后不会再动态读取 .env
所以这些环境变量如何配置,和你使用的部署工具有关
比如你用的 pm2
,在 ecosystem.config.cjs
,就可以配置 NODE_ENV
,但是我不推荐这样搞,因为如果代码要放在 github
上,就不要在任何一次提交中包含敏感的 token
除非你的 ecosystem.config.cjs
不在你的项目里,而是直接写在服务器上对应的文件夹里,每次打包时只覆盖 Nuxt 的部分
如果是用 Gitea
来自动化部署,就在 Gitea
的仓库设置中配置变量

正常情况只需要配置一次,因为正式环境没有需要经常改变的变量
以上就是如何使用 Github
的小 Demo
未完待续