从Next-Auth到Prisma,用最新潮的技术栈做登录
引言
使用React
框架的前端工程师应该都听过一句话:React
的成员不是在NextJS
就是在去NextJS
的路上。NextJS
的核心团队多来自React
,这正是NextJS
快速成长的原因之一。
那么NextJS
有什么特性呢?NextJS
为React
应用提供了非常便利的开箱即用功能,如路由、页面预获取、服务器端渲染等,极大地简化和加速了开发,这也让NextJS
成为前端领域的当红炸子鸡。
NextJS
背后的公司是Vercel
,这家公司还有当前最热门的自动化部署云平台Vercel
。
在NextJS
社区里,还有下一代Node.js
和TypeScript
的ORM
——Prisma
;还有英国开发者Iain Collins开发了next-auth
,这是一个支持多种登录方式如 OAuth、email、credentials
的库,能够极大简化我们开发登录功能的时间。
NextJS + Next-Auth + Prisma
,随着三个主角悉数亮相,就可以明确本文的目标了:用NextJS、Next-Auth、Prisma
来完成一个Github OAuth
登录的功能。
看完本文你将学到:
- 创建你的
Github
应用
- 在
NextJS
项目中使用next-auth
完成登录流程(不限于github
登录)
docker
构建开发环境postgres
数据库
- 当前最热门的
orm
——prisma
的基本使用
创建Github应用
本文假定你对OAuth
有基本的了解,如果你还不了解,找个可以扫码登录WeChat
的网站体验一下,那就叫OAuth
授权登录。
现在我们在自己的Github
后台创建一个应用,用户通过OAuth
授权登录,那就成为你这个应用的用户啦。
第一步:到 https://github.com/settings/apps 创建OAuth
应用
第二步:填写应用信息
注意:Authorization callback URL
是授权登录后的回调地址,如果登录流程是自己开发,你可以根据自己代码来填,但是本文是用next-auth
,所以得按next-auth
的规范来做,必须填/api/auth/callback/github
第三步:创建完成后,会进入应用后台,此时需要生成Client和secrets,并保存下Client ID和Client secrets。
因为现在还处于本地调试阶段,所以我把设置的两个URL改成localhost
了:
Github
应用创建就是这么简单,很适合用来做一些实验性的功能。
扩展阅读:
如果想学习Google
的OAuth
,请猛烈点击我的历史文章:
谷歌OAuth2.0开发的正确配置步骤
用Next-Auth实现登录
先创建一个Next
项目:
安装next-auth
在nextjs v13.2
推出后,next-auth
已支持app router
模式下在app
文件夹内构建API
,但是鉴于官方文档主要使用方式仍然是放在pages
文件夹下,所以本例也将在pages
下进行API
编写。
在pages/api/auth
中创建一个名为[...nextauth].ts
的文件
pages/api/auth/[...nextauth].ts
中使用[...nextauth]
是为了动态匹配nextauth
的所有API路由,如:
/api/auth/callback
处理认证回调
/api/auth/signin
处理登录
/api/auth/signout
处理登出
/api/auth/session
获取session
等等
也就是说,使用[...nextauth]
可以动态匹配所有包含/api/auth/
和nextauth
的API
路由。
我们把next-auth
的基本配置放在了lib/auth.ts
里:
next-auth
的服务端内容就是这些,乍一看容易一头雾水,但确实就是这么简单,它把中间繁琐的过程都封装起来了。
现在来写个这样的登录页
核心代码是「使用Github登录」的按钮
前端部分也完成了。
这时候还要配一个环境变量
现在试一下能不能完成Github OAuth
登录。点击按钮确实会跳到授权页
授权后会跳到首页,完成了授权登录流程了。
需要一个更准确的信息证明真的完成授权登录了?那就在首页把个人信息回显出来。这依然需要用到next-auth
的api
。让我们在lib
下面新建一个文件叫做session.ts
在app/page.tsx
调用
为了Image
可以生效,我们需要在next.config.js
里添加可信域
现在在首页就可以看到用户信息回显了
如果你自己开发过oauth
登录,再看到next-auth
的流程,你一定会很兴奋,因为next-auth
帮我们处理掉了很多中间过程。如果你没开发过oauth
,可以到这一篇看看自己开发oauth
登录有多麻烦:接入谷歌OAuth2.0登录的分析和代码实践
搭建postgres测试数据库
有时候我们不止是需要第三方授权的用户信息,我们还想自己保存一个用户表,把用户基本信息和我们自定义的一些字段共存,那么我们就需要建一个数据库了。
在Mysql
被oracle
收购后,postgres
成为开源社区里最闪亮的新星。postgres
也是本文代码用到的数据库。
如果我们自己安装postgres
,很多操作会显得非常繁琐,但如果在docker
中安装,一切就变得非常丝滑。
如果你还没安装docker
,请通过官网安装一下,安装后用命令验证是否安装成功,如果安装成功,会返回docker
的版本号。
docker安装完成后,到项目根目录下创建文件docker-compose.yml
启动docker
如果启动失败,请排查5432和8080端口是否被占用,如果被占用需要先关闭占用的服务再启动docker
。
现在访问http://localhost:8080
就可以登录数据库了
如果要关闭docker
,可以执行命令
如果你想学习Docker
的基本知识,请阅读文章:前端有了Docker,全栈之路更轻松了
用Prisma操作数据库
Prisma是下一代Node.js
和TypeScript
的ORM
。在Node中用过Sequelize
操作数据库的兄弟都知道,这是一个让你可以用写对象的方式来写sql
的工具,极大简化了前端对sql
的学习成本和开发成本,Prisma
也是这样的工具。
这里有对Prisma
和Sequelize
的简单优势对比:
Prisma
拥有自己的查询语言Prisma Query Language(PQL)
,语法更接近SQL,上手更简单。Sequelize
使用的是JS语法,需要学习更多API。
Prisma
有自动生成并更新数据库Schema
的功能,可以通过Prisma Client
直接访问数据库,更符合现代开发方式。Sequelize
需要更多手动配置。
Prisma
基于下一代ORM
理念,如无缝的关系映射、类型安全等特性。Sequelize
相对更传统。
Prisma
有更好的TypeScript
支持,提供良好的类型推导。Sequelize
的TypeScript
体验较差。
Prisma
有直观的数据模型可视化功能。Sequelize
需要通过代码理解数据结构。
Sequelize
社区更加成熟,资源更丰富。Prisma
作为较新框架,资源相对较少。
开始使用Prisma
初始化Prisma
初始化后,在根目录会出现一个prisma
的文件夹,这个文件夹用来存放Prisma
相关配置;里面还有一个schema.prisma
文件,是核心的数据库Schema
定义文件,开发时主要通过修改它来更新数据库模型设计。
再去看.env文件,会发现多了一条配置
需要改成我们的postgres配置
创建数据库
现在开始思考我们的用户表结构,未来我们希望通过next-auth
接入多个第三方平台的OAuth
,那么可以记录下用户在第三方平台的唯一id,还需要抹平不同平台的用户信息字段。那么就可以在用户表里添加sub
和platform
,再统一用户信息字段username
、avatar
。
schema.prisma
是唯一的Schema
定义文件,定义User
表结构如下:
定义了表结构后,本身不会自动创建表,需要执行migrate
命令才会由Prisma
来生成和执行创建表的SQL语句
打开数据库,会发现现在User
表已经创建出来了
如果你想深入了解一下prisma migrate
命令,请猛烈点击:prisma migrate命令简明教程
实例化PrismaClient
创建lib/prisma.ts
,实例化PrismaClient
PrismaClient
实例的作用是连接数据库并执行数据库操作,可以把它理解为一个数据库客户端,可以通过它来发送数据库查询、修改数据。
修改auth/ts
,我们尝试把从Github
获取的用户信息存到User
表里
回到页面,重新登录一下,会发现原本显示头像的位置不显示了,说明已经拿到我们封装后的用户信息了,只要修改一下字段就可以回显。
结语
通过本文的学习,我们用全新的技术栈NextJS+Next-Auth+Postgres+Prisma
完成了一个登录模块,如果你自己折腾过登录流程,一定能感受到Next-Auth
的强大。
本文涉及的技术栈,都是当前海外前端圈流行的新技术,比较适合个人开发者快速开发创意原型或实用工具。这套技术组合both前后端都能快速高效地工作,是构建web应用的绝佳选择。
源码与演示
源码:👉NextAuth-Prisma
在线演示:👉NextAuth登录
专栏资源
专栏介绍:以实战的角度进行Next.js生态圈的技术栈分享,内容包括但不限于:Next.js理论知识、功能模块设计思路、实战中使用到的技术栈。这是一个长期更新的专栏,我会持续把自己的思考和经验提炼分享出来,欢迎关注我的专栏👇
专栏地址:👉Next.js生态圈实战
专栏演示站:👉Next.js Demos
专栏源码仓库:👉Github - Source Code
交个朋友:👉加入「独立全栈交流群」