Laravel 7 + React.js 如何使用 Sanctum 做认证,第四部分
本系列文章讨论了如何使用 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 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。