如何使用Laravel和Nuxtjs进行身份验证,包括登录、注销和密码重置?
我找不到任何资源来帮助解决这个问题,有一些回购协议提供了某种类型的基础,但实际上没有多少有效 目标:运行Laravel有后端API,运行NuxtJS作为前端SPA,可以是两个单独的位置,也可以组合成一个 需要在两个系统之间进行适当的身份验证才能登录用户。看起来可以解决一些SPA问题,但很难找到真正显示完整设置示例的适当文档如何使用Laravel和Nuxtjs进行身份验证,包括登录、注销和密码重置?,laravel,vue.js,nuxt.js,laravel-8,Laravel,Vue.js,Nuxt.js,Laravel 8,我找不到任何资源来帮助解决这个问题,有一些回购协议提供了某种类型的基础,但实际上没有多少有效 目标:运行Laravel有后端API,运行NuxtJS作为前端SPA,可以是两个单独的位置,也可以组合成一个 需要在两个系统之间进行适当的身份验证才能登录用户。看起来可以解决一些SPA问题,但很难找到真正显示完整设置示例的适当文档 测试了这个想法,但失败了,不能与npm一起工作,必须使用纱线,但是,登录错误,不能开箱即用。回购需要努力 本教程非常深入,看起来很有希望,但是,刷新令牌似乎不适用于SPA端
希望这不是一个太宽泛的主题,因为如果不自己编写太多核心代码,很难找到合适的教程或文档,因此需要寻找一些关于这个问题的指导。似乎许多人在将前后两个域分开时,很难实现Sanctum for SPA身份验证,问题通常与CORS有关。Sanctum文档很好,但是假设对CORS有一定的了解(或者假设请求的来源相同)。在我看来,我将分解设置,在我觉得文档不足的地方提供一些额外的支持。答案很长,但最后我将回答您的问题,该问题似乎特别侧重于身份验证 摘自圣殿文献: 首先,您应该配置您的SPA将从哪些域发出请求 假设您的前端应用程序位于,域是什么?那么...怎么样http://localhost:3000? 域映射到IP地址,而不是协议或端口号。因此,给定示例中的域是和localhost。考虑到这一点,在这一阶段需要做的就是转到config目录中的
sanctum.php
文件,设置'stateful'
键的值,以匹配您的Laravel API将从中接收请求的域虽然根据定义,域名不包括端口号,但Sanctum文档非常清楚,如果您通过需要特定端口的URL进行访问,这也是必需的。
/config/sanctum.php
...
'stateful' => [
'localhost:3000',
],
或
.env文件在这里很有用
如果您在使用在单独子域上执行的SPA对应用程序进行身份验证时遇到问题,则可能是错误配置了CORS(跨源资源共享)或会话cookie设置
的确如此。那么正确的设置是什么样的呢?假设最近的Laravel版本使用了fruitcake/Laravel cors包,那么/config文件夹中将有一个cors.php文件。默认设置如下所示:
默认值
/config/cors.php
...
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,
我们有一些工作要做。首先是路径。目前,我们的Laravel API设置为只允许来自任何外部来源的请求尝试访问/API/routes*。正如Sanctum文档所要求的,当我们尝试从路径/Sanctum/csrf cookie
访问csrf cookie时,这可能会导致早期的问题。cors.php文件中不明确允许对此路径的请求,因此它们将失败。要解决此问题,我们可以这样做:
'paths' => [
'api/*',
'sanctum/csrf-cookie'
]
现在,对/sanctum/csrf cookie的请求将被允许。作为旁注,我个人认为将前缀从sanctum
更改为api
,这样我就可以为我的http客户端(通常是axios)设置一个基本url,这非常有用
要更改路径,可以在/config/sanctum.php文件中更改以下内容:
'prefix' => 'api',
'domain' => '.my-awesome-app.io',
现在,对/api/csrf cookie的GET请求将返回cookie,而不是/sanctum/csrf cookie
接下来是允许的来源
。默认情况下,它设置为*
,表示“任意原点”。来源是向您的Laravel API发送请求的应用程序的协议、域和端口号。回到我们前面的例子,它们的起源是http://localhost:3000
和https://www.my-awesome-app.io
。以下是允许前端应用程序发出请求时应使用的确切值:
'allowed_origins' => ['http://localhost:3000'],
我建议将其移动到.env文件中,并为本地和生产使用单独的源文件
/config/cors.php
...
'allowed_origins' => [env('ALLOWED_ORIGINS')],
/.env
...
ALLOWED_ORIGINS=http://localhost:3000
文档中提到了cors配置的最后一部分,即
'supports_credentials' => false,
必须更改为:
'supports_credentials' => true,
我们的/config/cors.php文件现在看起来像:
已修改
/config/cors.php
...
'paths' => [
'api/*',
'sanctum/csrf-cookie'
],
'allowed_methods' => ['*'],
'allowed_origins' => [env('ALLOWED_ORIGINS')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
奖金信息,Chrome将不允许向返回报头的服务器发出认证请求
访问控制允许原点:
因此,您应该确保在cors配置中设置了特定的原点
最后,您应该确保应用程序的会话cookie域配置支持根域的任何子域。您可以通过在域前面加一个前导字符来实现这一点。在会话配置文件中:
这并不复杂,但似乎它能让人们注意到,所以我想我会提到它。以我们的例子来看
/config/cors.php
...
'paths' => [
'api/*',
'sanctum/csrf-cookie'
],
'allowed_methods' => ['*'],
'allowed_origins' => [env('ALLOWED_ORIGINS')],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
'domain' => '.my-awesome-app.io',
'domain' => 'localhost',
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Validation\ValidationException;
class LoginController extends Controller
{
public function login(Request $request)
{
$request->validate([
'email' => ['required', 'email'],
'password' => 'required'
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
return response()->json(Auth::user(), 200);
}
throw ValidationException::withMessages([
'email' => 'The provided credentails are incorect.'
]);
}
}
/middleware/auth-check.js
export default async function ({ store, redirect }) {
// Check if the user is not already in the store.
if (store.state.user === null) {
// Call your Laravel API to get the currently authenticated user.
// It doesn't matter if the store has been wiped out due to a page
// refresh- the browser still has the cookies, which will be sent
// along with this request.
try {
let rsp = await user.getAuthenticatedUser()
// If we get the user from the Laravel API, push it back in to
// the store and carry on to the page.
store.commit('SET_AUTH_USER', rsp.data)
} catch (e) {
// If our API doesn't return the user for any reason, redirect to
// the login page.
return redirect('/login')
}
}
// If not, carry on to the page.
}
/pages/admin.vue
export default {
middleware: auth-check
}