introduction
认证验证了用户谁?,然后授权控制那个用户能够访问什么. next.js 支持多种验证模式,每一种设计用于不同的使用场景,现在让我们来了解每一种使用情况(基于我们的约束来选择) ..
认证模式
第一步式标识需要哪一种认证模式(理解你想要的数据抓取策略) .. 种类有两种主要的模式
- 使用静态生成取服务器渲染一个加载状态,剩下的通过客户端用户数据抓取
- 在服务端抓取用户信息减少未认证内容的闪烁 …
认证静态生成的页面
next.js 自动的判断一个页面式静态(如果它没有阻塞式数据抓取需求),这就意味着页面中缺少getServerSideProps
以及 getInitialProps
,相反,你的页面能从服务器上渲染一个加载状态,后续通过客户端进行数据加载 ..
这个模式的好处是它允许页面能够被全局CDN 提供且假设并使用next/link
进行预加载,尤其是这导致更快的TTI(Time to Interactive) ..
让我们查看一个profile 页面,它最初加载一个骨架,一旦用户的请求完成,它将展示一个用户的名称 …
// pages/profile.js
import useUser from '../lib/useUser'
import Layout from '../components/Layout'
const Profile = () => {
// Fetch the user client-side
const { user } = useUser({ redirectTo: '/login' })
// Server-render loading state
if (!user || user.isLoggedIn === false) {
return <Layout>Loading...</Layout>
}
// Once the user request finishes, show the user
return (
<Layout>
<h1>Your Profile</h1>
<pre>{JSON.stringify(user, null, 2)}</pre>
</Layout>
)
}
export default Profile
你能够查看 这个示例 https://iron-session-example.vercel.app/,检查 with-iron-session示例查看它如何工作 ..
认证服务器渲染页面
如果你从页面上导出了一个async
函数叫做 getServerSideProps
,Next.js 将预渲染这个页面(每次请求的时候,将使用从这个函数返回的数据) …
export async function getServerSideProps(context) {
return {
props: {}, // Will be passed to the page component as props
}
}
上面的例子直接改造为服务端渲染 示例 ,如果这里包含一个会话,返回user
作为一个在页面中Profile
组件的属性,注意到这个例子中并没有加载骨架 …
// pages/profile.js
import withSession from '../lib/session'
import Layout from '../components/Layout'
export const getServerSideProps = withSession(async function ({ req, res }) {
const { user } = req.session
if (!user) {
return {
redirect: {
destination: '/login',
permanent: false,
},
}
}
return {
props: { user },
}
})
const Profile = ({ user }) => {
// Show the user. No loading state is required
return (
<Layout>
<h1>Your Profile</h1>
<pre>{JSON.stringify(user, null, 2)}</pre>
</Layout>
)
}
export default Profile
这种模式的优势是在重定向之前能够减少未认证内容的闪烁 .. 但是getServerSideProps
中抓取用户数据会阻塞渲染直到请求被认证提供器所解析为止 .. 为了阻止创建一个瓶颈并提高你的TTFB(第一个字节到达的时间),你应该确保认证尽可能快,否则应该考虑静态生成 ….
认证提供器
现在来学习一下认证模式,查看特定的提供器并暴露它如何在Next.js中使用 …
携带自己的数据库
如果我存在一个具有用户数据的数据库,你可能想要利用一个开源的解决方案 …
- 如果你想底层,加密并且无状态会话工具,使用
iron-session
- 如果你想要具有全部特性的认证系统(且内置了各种提供器- google ,facebook,github),以及 JWT,JWE,email/password,magic links ,那么使用
next-auth
这些库支持认证模式,如果你喜欢 Passport,我们也可以使用安全以及加密的cookie ..