我理解的一般流程是
一个。应用程序/客户端通过传递 client-id、scope、redirect_uri 向资源服务器请求授权代码
b。资源服务器提示用户使用他们的凭据登录并授权,然后重定向回客户端中的回调 url
c。然后客户端使用授权码请求访问令牌。
d。如果一切顺利,资源服务器返回访问令牌和刷新令牌
e。客户端将访问令牌和刷新令牌存储在 http cookie 中
但是,在步骤 b 中,我希望用户登录然后重定向到 OTP 页面
然后将他们重定向回客户端中的回调 url
我的想法
一个。让用户登录b。创建一个范围为 request_otp_payment 的访问令牌和一个中间件为 auth:api 且范围为 request_otp_payment 的路由,以便只有登录用户和具有范围为 request_otp_payment 的令牌的用户才能访问此路由。
c。用户登录后,api 返回一个令牌并将其重定向到 otp 页面
d。一旦用户被重定向并输入 otp,我将撤销此令牌。
问题
我被 csrf 令牌不匹配困住了
我的代码
//Web.php
Route::get('/otp', [AuthController::class, 'otpPage'])->name('requireotp')->middleware(['auth', 'scope:request_otp_payment']);
Route::middleware('guest')->group(function () {
Route::get('login', [AuthController::class, 'create'])->name('login');
Route::post('login', [AuthController::class, 'store'])->name('login.store');
});
//AuthController.php
class AuthController extends Controller
{
public function create(Request $request): Response
{
return Inertia::render('Passport/Login', [
'canResetPassword' => Route::has('password.request'),
'status' => session('status'),
]);
}
public function store(Request $request)
{
$user = null;
$token = null;
$validator = Validator::make($request->all(), [
'email' => 'required|string|email|max:255',
'password' => 'required|string|min:6',
]);
if ($validator->fails()) {
$errors = $validator->errors();
return response(['errors' => $errors], 422);
}
$user = User::where('email', $request->email)->first();
if ($user) {
if (Hash::check($request->password, $user->password)) {
$token = $user->createToken('otp Token', ['request_otp_payment'])->accessToken;
$response = ['token' => $token];
return response($response, 200);
} else {
return throw ValidationException::withMessages([
'email' => [trans('auth.failed')],
]);
}
} else {
return throw ValidationException::withMessages([
'email' => [trans('auth.failed')],
]);
}
}
public function otpPage(Request $request)
{
$intended_route = $request->session()->get('url')['intended'];
$state = $request->session()->pull('state');
return Inertia::render('Passport/Otp', [
'intendedRoute' => $intended_route,
'state' => $state
]);
}
}
//Login.jsx
const submit = async (e) => {
e.preventDefault();
console.log("submitting to Passport Post Route...");
// post(route("login.store"));
try {
const response = await axios.post(route("login.store"), {
email: data.email,
password: data.password,
});
const { token } = response?.data;
if (token) {
console.log("hrere");
return Inertia.visit("/otp"); //once, i get the token, i redirect them to the otp page
}
} catch (error) {
const errorResponse = error?.response?.data?.errors;
//returns array of errors
if (errorResponse) {
setError({
email: errorResponse.email ? email[0] : null,
password: errorResponse.password ? password[0] : null,
});
}
}
};
这是我对工作流程的总体思路,我不确定,如果这是正确的做法,请随时指正。非常感谢