JWT身份验证流程

了解如何使用我们的 FoodAdvisor 示例对 REST API 查询进行身份验证

示例手册:使用 JWT 的身份验证流程

此页面是后端自定义示例手册的一部分。请确保您已阅读其 简介

💭 上下文:

开箱即用,FoodAdvisor 的前端网站不提供任何登录功能。登录是通过访问 localhost:1337/admin 上的 Strapi 管理面板完成的。

让我们在前端添加一个基本的登录页面,这个由 Next.js 提供支持的网站包含在 FoodAdvisor 的 /client 文件夹中。登录页面可通过 localhost:3000/auth/login 访问,并包含一个典型的电子邮件/密码登录表单。这将允许以编程方式验证发送到 Strapi 的 API 请求。

前端网站上登录表单的可能示例

🎯 目标:

创建一个前端组件以:

  1. 显示登录表单,
  2. 向 Strapi 后端服务器的 /auth/local 路由发送请求以进行身份验证,
  3. 获取 JSON Web Token (JWT),
  4. 并将 JWT 存储到浏览器的 localStorage 属性,以便稍后检索和验证我们的请求。

有关 JWT 身份验证的其他信息,请参阅 用户和权限插件 文档。

🧑‍💻 代码示例:

本节中的代码示例使用 formik 包。使用 yarn add formiknpm install formik 安装它并重新启动开发服务器。

为此,在 FoodAdvisor 项目的 /client 文件夹中,您可以创建一个包含以下示例代码的 pages/auth/login.js 文件。突出显示的行显示发送到 Strapi 的用户和权限插件提供的 /auth/local 路由的请求:

/client/pages/auth/login.js
jsx
import React from 'react'
import { useFormik } from 'formik'
import { Button, Input } from '@nextui-org/react'
import Layout from '@/components/layout'
import { getStrapiURL } from '@/utils'

function Login() {
  const { handleSubmit, handleChange } = useFormik({
    initialValues: {
      identifier: '',
      password: '',
    },
    onSubmit: async (values) => {
      /**
       * API URLs in Strapi are by default prefixed with /api,
       * but because the API prefix can be configured
       * with the rest.prefix property in the config/api.js file,
       * we use the getStrapiURL() method to build the proper full auth URL.
       */
      const res = await fetch(getStrapiURL('/auth/local'), {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(values),
      })
      /**
       * Gets the JWT from the server response
       */
      const { jwt } = await res.json()
      /**
       * Stores the JWT in the localStorage of the browser.
       * A better implementation would be to do this with an authentication context provider
       * or something more sophisticated, but it's not the purpose of this tutorial.
       */
      localStorage.setItem('token', jwt)
    },
  })
  /**
   * The following code renders a basic login form
   * accessible from the localhost:3000/auth/login page.
   */
  return (
    <Layout>
      <div className="h-full w-full flex justify-center items-center my-24">
        <form onSubmit={handleSubmit} className="flex flex-col gap-y-6 w-4/12">
          <h1 className="font-bold text-3xl mb-6">Login</h1>
          <Input
            onChange={handleChange}
            type="email"
            name="identifier"
            label="Email"
            placeholder="Enter your email"
          />
          <Input
            type="password"
            name="password"
            label="Password"
            placeholder="Enter your password"
            onChange={handleChange}
          />
          <Button type="submit" className="bg-primary rounded-md text-muted">
            Login
          </Button>
        </form>
      </div>
    </Layout>
  )
}

export default Login

What's next?

Learn more about how custom services and controllers can help you tweak a Strapi-based application.