Laravel 7 + React.js 如何使用 Sanctum 做认证,第四部分

Laravel

本系列文章讨论了如何使用 Laravel Sanctum 为前端 React 应用程序提供身份验证。 在第一部分中,我概述了构建和配置Laravel后端所需的步骤。 第二部分讨论了React 应用程序的 UI 显示,包括应用程序状态和 React 上下文的使用。 第三部分逐步介绍了用户如何登录和认证。 最后一篇文章将重点介绍用户注册过程。

作为参考,有 已完成应用程序 以及 React客户端Laravel服务端 的源代码.

注册流程

在用户使用我们的应用程序之前,她必须先注册,向该应用程序提供一些个人信息,这些信息可以在将来用于识别她的身份。 以下是完成此注册所需的步骤。

  • User - 用户填写注册表单。

  • User - 用户单击“注册”按钮。

  • React - React 将消息发送到 API sanctum/csrf-cookie 端点。

  • Laravel - Laravel 响应 CSRF令牌。

  • React - React 将 POST 消息以及用户提供的邮箱和密码信息发送到 api/register API 。

  • Laravel - Laravel 将端点与我们在 routes/api.php 文件中创建的路由进行匹配,并在UserController 中调用 login 函数。

  • Laravel - UserController 中的登录函数调用 Auth 类中的函数,以使用用户提供的凭据对身份进行验证。

  • Laravel - 如果验证成功,Laravel 会向创建新用户,并添加到数据库,然后向浏览器返回200消息,否则会返回 422 消息。

  • React -如果注册成功,React 将 GET 消息发送到 api/user API。

  • Laravel - Laravel 将端点与 route/api.php 文件中的路由匹配,并返回包含 userId 的新用户信息。

  • React - React 接收用户信息并更新状态下的 userId 和 userName。

  • React - authStatus 设置为 LOGGED_IN,并且向用户显示注销组件。

注册相关代码

现在,我们将回顾完成每个步骤的代码。

当用户单击注册按钮时,将运行 AppContext 中的 signup 函数。 首先要做的是将 axios 的 withCredentials 属性设置为 true。

// REACT APP src/contexts/AppContext.js - signup()
const login = () => {
    axios.defaults.withCredentials = true;

然后使用 axios 将GET消息发送到 sanctum/csrf-cookie 端点。 Laravel 使用 CSRF 令牌进行响应,然后将其附加到对 API 的所有后续调用中,从而保护应用程序免受跨站点伪造请求的侵害。

// REACT APP src/contexts/AppContext.js - signup()
// CSRF COOKIE
    axios.get(hostName + "sanctum/csrf-cookie").then(

接下来,axios 将 POST 请求以及用户在注册表单中输入的用户名,电子邮件和密码发送到 api/register 端点。

// REACT APP src/contexts/AppContext.js - signup()
// SIGNUP / REGISTER
axios.post(hostName + "api/register", {
  name: userNameInput,
  email: userEmail,
  password: userPassword,
})

Laravel 将端点与在 routes/api.php 文件中创建的路由匹配,并在 UserController 中调用 register 函数。

// LARAVEL APP routes/api.php
Route::post('/register', 'UserController@register');

UserController 中的 register 函数验证用户提供的信息。 并创建一个新的用户记录,将其添加到数据库中,如果创建成功,则显示200消息。

// LARAVEL APP app/Http/Controllers/UserController.php
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();
        $user = $this->create($request->all());
        $this->guard()->login($user);
        return response()->json([
            'user' => $user,
            'message' => 'registration successful'
        ], 200);
    }
    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            //'password' => ['required', 'string', 'min:4', 'confirmed'],
            // NO PASSWORD CONFIRMATION
            'password' => ['required', 'string', 'min:4'],
        ]);
    }

如果注册成功,React 将 GET 消息发送到 api/user API 。

// REACT APP src/contexts/AppContext.js - signup()
// GET USER
axios.get(hostName + "api/user").then(

Laravel 将端点与 route/api.php 文件中的路由匹配,并返回当前登录的用户。

// LARAVEL APP routes/api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

React 接收用户信息并更新状态下的 userId 和 userName。 authStatus 设置为 LOGGED_IN,这将导致注销组件显示给用户。

// REACT APP src/contexts/AppContext.js - signup()
(response) => {
    //console.log(response);
    setUserId(response.data.id);
    setUserName(response.data.name);
    setErrorMessage("");
    setAuthStatus(LOGGED_IN);
},

整个注册功能如下所示。 如果对 API 的任何调用导致返回错误响应,则会创建错误消息,并通过errorMessage 状态属性将其显示给用户。

// REACT APP src/contexts/AppContext.js - signup()
const signup = () => {
  axios.defaults.withCredentials = true
  // CSRF COOKIE
  axios.get(hostName + "sanctum/csrf-cookie").then(
    (response) => {
      //console.log(response);
      // SIGNUP / REGISTER
      axios
        .post(hostName + "api/register", {
          name: userNameInput,
          email: userEmail,
          password: userPassword,
        })
        .then(
          (response) => {
            //console.log(response);
            // GET USER
            axios.get(hostName + "api/user").then(
              (response) => {
                //console.log(response);
                setUserId(response.data.id)
                setUserName(response.data.name)
                setErrorMessage("")
                setAuthStatus(LOGGED_IN)
              },
              // GET USER ERROR
              (error) => {
                setErrorMessage("Could not complete the sign up")
              }
            )
          },
          // SIGNUP ERROR
          (error) => {
            if (error.response.data.errors.name) {
              setErrorMessage(error.response.data.errors.name[0])
            } else if (error.response.data.errors.email) {
              setErrorMessage(error.response.data.errors.email[0])
            } else if (error.response.data.errors.password) {
              setErrorMessage(error.response.data.errors.password[0])
            } else if (error.response.data.message) {
              setErrorMessage(error.response.data.message)
            } else {
              setErrorMessage("Could not complete the sign up")
            }
          }
        )
    },
    // COOKIE ERROR
    (error) => {
      setErrorMessage("Could not complete the sign up")
    }
  )
}

注销

现在剩下的只是注销功能。 此过程非常简单。

  • 用户按下注销按钮。

  • React 运行 AppContext logout 函数。

  • Axios 调用 api /logout API。

// REACT APP src/contexts/AppContext.js - logout()
function logout() {
  axios.defaults.withCredentials = true
  axios.get(hostName + "api/logout")
  • Laravel 将端点与我们在 routes/api.php 文件中创建的路由匹配,并在 UserController 中调用注销函数。
// LARAVEL APP routes/api.php
Route::post('/logout', 'UserController@logout');
  • UserController 中的 logout 函数将用户注销,并向浏览器返回 200 消息。
// LARAVEL APP app/Http/Controllers/UserController.php
public function logout()
{
    Auth::logout();
    return response()->json(['message' => 'Logged Out'], 200);
}
  • 然后,React 中的 logout() 函数将重新初始化应用程序状态。 authStatus 设置为 NOT_LOGGED_IN,这将使用户返回到其开始的位置,从而显示原始的初始屏幕。 这是整个 logout() 函数。
// REACT APP src/contexts/AppContext.js - logout()
function logout() {
  axios.defaults.withCredentials = true
  axios.get(hostName + "api/logout")
  setUserId(0)
  setUserName("")
  setUserNameInput("")
  setUserEmail("")
  setUserPassword("")
  setAuthStatus(NOT_LOGGED_IN)
}
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://dev.to/dog_smile_factory/authent...

译文地址:https://learnku.com/laravel/t/43732

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!