introduction

认证验证了用户谁?,然后授权控制那个用户能够访问什么. next.js 支持多种验证模式,每一种设计用于不同的使用场景,现在让我们来了解每一种使用情况(基于我们的约束来选择) ..

认证模式

第一步式标识需要哪一种认证模式(理解你想要的数据抓取策略) .. 种类有两种主要的模式

  • 使用静态生成取服务器渲染一个加载状态,剩下的通过客户端用户数据抓取
  • 在服务端抓取用户信息减少未认证内容的闪烁 …

认证静态生成的页面

next.js 自动的判断一个页面式静态(如果它没有阻塞式数据抓取需求),这就意味着页面中缺少getServerSideProps以及 getInitialProps,相反,你的页面能从服务器上渲染一个加载状态,后续通过客户端进行数据加载 ..

这个模式的好处是它允许页面能够被全局CDN 提供且假设并使用next/link进行预加载,尤其是这导致更快的TTI(Time to Interactive) ..

让我们查看一个profile 页面,它最初加载一个骨架,一旦用户的请求完成,它将展示一个用户的名称 …

  1. // pages/profile.js
  2. import useUser from '../lib/useUser'
  3. import Layout from '../components/Layout'
  4. const Profile = () => {
  5. // Fetch the user client-side
  6. const { user } = useUser({ redirectTo: '/login' })
  7. // Server-render loading state
  8. if (!user || user.isLoggedIn === false) {
  9. return <Layout>Loading...</Layout>
  10. }
  11. // Once the user request finishes, show the user
  12. return (
  13. <Layout>
  14. <h1>Your Profile</h1>
  15. <pre>{JSON.stringify(user, null, 2)}</pre>
  16. </Layout>
  17. )
  18. }
  19. export default Profile

你能够查看 这个示例 https://iron-session-example.vercel.app/,检查 with-iron-session示例查看它如何工作 ..

认证服务器渲染页面

如果你从页面上导出了一个async函数叫做 getServerSideProps,Next.js 将预渲染这个页面(每次请求的时候,将使用从这个函数返回的数据) …

  1. export async function getServerSideProps(context) {
  2. return {
  3. props: {}, // Will be passed to the page component as props
  4. }
  5. }

上面的例子直接改造为服务端渲染 示例 ,如果这里包含一个会话,返回user 作为一个在页面中Profile组件的属性,注意到这个例子中并没有加载骨架 …

  1. // pages/profile.js
  2. import withSession from '../lib/session'
  3. import Layout from '../components/Layout'
  4. export const getServerSideProps = withSession(async function ({ req, res }) {
  5. const { user } = req.session
  6. if (!user) {
  7. return {
  8. redirect: {
  9. destination: '/login',
  10. permanent: false,
  11. },
  12. }
  13. }
  14. return {
  15. props: { user },
  16. }
  17. })
  18. const Profile = ({ user }) => {
  19. // Show the user. No loading state is required
  20. return (
  21. <Layout>
  22. <h1>Your Profile</h1>
  23. <pre>{JSON.stringify(user, null, 2)}</pre>
  24. </Layout>
  25. )
  26. }
  27. export default Profile

这种模式的优势是在重定向之前能够减少未认证内容的闪烁 .. 但是getServerSideProps中抓取用户数据会阻塞渲染直到请求被认证提供器所解析为止 .. 为了阻止创建一个瓶颈并提高你的TTFB(第一个字节到达的时间),你应该确保认证尽可能快,否则应该考虑静态生成 ….

认证提供器

现在来学习一下认证模式,查看特定的提供器并暴露它如何在Next.js中使用 …

携带自己的数据库

如果我存在一个具有用户数据的数据库,你可能想要利用一个开源的解决方案 …

  • 如果你想底层,加密并且无状态会话工具,使用iron-session
  • 如果你想要具有全部特性的认证系统(且内置了各种提供器- google ,facebook,github),以及 JWT,JWE,email/password,magic links ,那么使用next-auth

这些库支持认证模式,如果你喜欢 Passport,我们也可以使用安全以及加密的cookie ..

其他提供器

examples folder中包含了各种其他的认证提供器 …