如何将Laravel和Nuxtjs与Authentication一起使用,包括登录,注销和密码重置? [英] How to use Laravel and Nuxtjs with Authentication, including login, logout, and password resets?

查看:67
本文介绍了如何将Laravel和Nuxtjs与Authentication一起使用,包括登录,注销和密码重置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到任何资源可以解决此问题,有一些存储库提供了某种类型的基础,但是实际上没有多少存储库可以工作.

I can't find any resource to help with this issue, there are some repos that provide some type of base, but not many of them actually work.

目标:运行Laravel具有后端API,运行NuxtJS作为前端SPA,可以是2个单独的位置,也可以合并为一个.

Goals: Run Laravel has the backend API, run NuxtJS as the frontend SPA, either 2 separate locations or combined into one.

需要在两个系统之间进行正确的身份验证才能登录用户. Laravel Sanctum 希望解决一些SPA问题,但是很难找到合适的文档来显示完全设置示例.

Needs to have proper authentication between both systems for logging in users. Laravel Sanctum looks to solve some of the SPA issues, but its hard to find proper documentation that actually shows a fully setup example.

  1. 测试了此想法 https://github.com/zondycz/laravel-nuxt-sanctum 但是失败了,不能与npm一起使用,必须使用yarn,但是,登录错误却不能立即使用.回购需要工作.

  1. Tested this idea https://github.com/zondycz/laravel-nuxt-sanctum But has failed, doesnt work with npm, must use yarn, however, login errors, doesnt work out of box. Repo needs work.

本教程

This tutorial Secure authentication in Nuxt SPA with Laravel as back-end was very indepth, and looked promising, however, refresh tokens don't seem to work with the SPA side since the author developed it on static nuxt. Though I feel like it could be modified to work, I havent found the solution yet.

此模板 Laranuxt 看起来很有希望,尽管我尚未尝试,我不确定他们是否现在会定期对其进行更新,该文件先前是 Laravel Nuxt JS构建的(废弃的项目)

This template, Laranuxt looked very promising, though I've yet to try it, im not sure if they are regularly updating it at this point, which was previously built by Laravel Nuxt JS (abandoned project)

我能够运行#2,虽然刷新令牌不能完全起作用,但我仍然可以验证用户身份,但是现在另一个问题是密码重置,我无法通过nuxt表单正确设置.

I was able to run the #2, while refresh tokens dont exactly work, I can still authenticate the user, but now the other issue is password resets, which I'm unable to properly setup through the nuxt form.

有人通过这些框架之间的通信找到了资源或解决了这个问题吗?还是我要去做一个似乎看不到尽头的兔子洞?

Has anyone found resources or solved this issue with communication between these frameworks? or am I going done a rabbit hole that seems to have no end in sight?

我想可以用另一种方式说,您可以建立一个完全宁静的身份验证系统吗?

I guess another way could be saying, can you do a fully restful authentication system?

希望这不是一个广泛的话题,希望在此问题上寻求一些指导,因为很难找到合适的教程或文档而又不用自己编写太多核心代码.

Hopefully this isn't too broad of a topic, looking for some guidance on this issue as its hard to find proper tutorials or documentation without writing too much core code myself.

推荐答案

似乎很多人在将正面和背面拆分为单独的域时都难以实施Sanctum进行SPA身份验证,并且该问题通常与CORS有关.Sanctum文档很棒,但是假设您具有CORS的知识(或假设请求的来源相同).我将按照我的看法分解设置,在我觉得文档不足的地方提供一些额外的支持.答案很长,但最后我会 解决您的问题,该问题似乎专门针对身份验证.

It seems many people struggle to implement Sanctum for SPA authentication when splitting the front and back across separate domains, and the problem is usually CORS related. The Sanctum documentation is great, but assumes a knowledge of CORS (or assumes requests will be same-origin). I'll break down the setup as I see it, providing a little extra support where I feel the docs fall short. A long answer, but towards the end I will address your question which seems to focus specifically on authentication.

来自Sanctum文档:

首先,您应该配置您的SPA将向哪个发出请求.

First, you should configure which domains your SPA will be making requests from.

假设您的前端应用程序位于 https://www.my-awesome-app.io 是什么?那http://localhost:3000呢?域映射到IP地址,而不是协议或端口号.因此,给定示例中的域为 www.my-awesome-app.io localhost .考虑到这一点,在此阶段您要做的就是转到配置目录中的 sanctum.php 文件,并将'stateful'键的值设置为匹配您的Laravel API将接收来自其请求的域.尽管域名从定义上讲不包括端口号,但Sanctum文档清楚地表明,如果通过需要特定端口的URL进行访问,这也是必需的.

Assuming your front-end app lives at https://www.my-awesome-app.io, what is the domain? What about http://localhost:3000? Domains map to IP addresses, not protocols or port numbers. So the domains in the given examples would be www.my-awesome-app.io and localhost. With that in mind, all you need to do at this stage is go to the sanctum.php file in your config directory and set the value of the 'stateful' key to match the domain your Laravel API will receive requests from. Although domain names by definition do not include port numbers, the Sanctum docs make it very clear this is also required if you're accessing via a URL that requires a specific port.

/config/sanctum.php
...
'stateful' => [
    'localhost:3000',
],

'stateful' => [
    'my-awesome-app.io',
],

.env文件在这里很有用.

.env files are useful here.

如果您无法通过在单独的子域上执行的SPA对应用程序进行身份验证,则可能配置了错误的CORS(跨源资源共享)或会话Cookie设置.

的确.那么正确的设置是什么样的呢?假设使用fruitcake/laravel-cors软件包的是最新的Laravel版本,则/config文件夹中将有一个cors.php文件.默认外观如下:

Indeed. So what does a correct setup look like? Assuming a recent Laravel version using the fruitcake/laravel-cors package, you will have a cors.php file in your /config folder. The default looks like:

默认

/config/cors.php
...
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => false,

我们要在这里做一些工作.首先, paths .目前,我们的Laravel API已设置为仅在尝试访问/api/路由时才允许来自任何外部来源 的请求*.如Sanctum文档所要求的那样,这可能会在早期导致我们尝试从路径/sanctum/csrf-cookie 访问csrf cookie时引起麻烦.在我们的cors.php文件中,未明确允许对此路径的请求,因此它们将失败.要解决,我们可以这样做:

We have some work to do here. First, the paths. At the moment, our Laravel API is set up to allow requests from any external origin only if they are trying to access the /api/ routes*. This can lead to trouble early on when, as the Sanctum docs require, we try to access a csrf cookie from the path /sanctum/csrf-cookie. Requests to this path are not explicitly permitted in our cors.php file, so they will fail. To fix, we could do this:

'paths' => [
    'api/*',
    'sanctum/csrf-cookie'
]

,现在将允许对/sanctum/csrf-cookie的请求.作为旁注,我个人认为将前缀从 sanctum 更改为 api 很有用,这样我就可以为我的http客户端(通常是axios)设置一个基本的url.

and now requests to /sanctum/csrf-cookie will be permitted. As a sidenote, I find it personally very useful to change the prefix from sanctum to api, that way I can set a single base url for my http client (usually axios).

import axios from 'axios';

axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://localhost:3000/api';

要更改路径,可以在/config/sanctum.php文件中更改以下内容:

To change the path, you can change the following in the /config/sanctum.php file:

'prefix' => 'api',

现在对/api/csrf-cookie的GET请求将返回cookie,而不是/sanctum/csrf-cookie.

Now GET requests to /api/csrf-cookie will return the cookie, instead of /sanctum/csrf-cookie.

接下来,是 allowed-origins .默认情况下,它设置为 * ,表示任何来源".来源是向您的Laravel API发送请求的应用的协议,域和端口号.因此,回到我们之前的示例,它们的起源将是 http://localhost:3000 https://www.my-awesome-app.io .这些是您应该用来允许来自前端应用程序的请求的确切值:

Next, the allowed-origins. By default, it is set to *, which means "any origin". An origin is the protocol, domain and port number of the app sending a request to your Laravel API. So going back to our earlier examples, their origins would be http://localhost:3000 and https://www.my-awesome-app.io. These are the exact values you should use to allow requests from your front-end app:

'allowed_origins' => ['http://localhost:3000'],

我建议将其移动到.env文件,并为本地和生产使用单独的来源.

I would recommend moving this to the .env file, and having a separate origin for local and production.

/config/cors.php
...
'allowed_origins' => [env('ALLOWED_ORIGINS')],


/.env
...
ALLOWED_ORIGINS=http://localhost:3000

文档中确实提到了我们的cors配置的最后一部分,即

The documentation does mention the last part of our cors config, which is that

'supports_credentials' => false,

必须更改为:

'supports_credentials' => true,

我们的/config/cors.php文件现在如下所示:

Our /config/cors.php file now looks like:

已修改

/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将不允许向返回标头的服务器发送凭证请求 Access-Control-Allow-Origin:*

Bonus info, Chrome will not allow a credentialed request to a server that returns the header Access-Control-Allow-Origin: *

Google Chrome浏览器:如果凭据标记为true,则不能在"Access-Control-Allow-Origin"标头中使用通配符"*"

因此,您应该确保在cors配置中设置了特定来源!

So you should make sure you set a specific origin in your cors config!

最后,应确保应用程序的会话cookie域配置支持根域的任何子域.您可以通过在域名前加上前导前缀来实现此目的.在您的会话配置文件中:

这并不复杂,但是似乎可以吸引人们,所以我以为提到了这一点.鉴于目前的示例,我们将对config/session.php文件进行以下更改:

This isn't complicated, but seems it can catch people out so thought I'd mention it. Given our examples so far, we'd make the following change to our config/session.php file:

'domain' => '.my-awesome-app.io',

在本地,单独使用 localhost 即可:

Locally, localhost alone is fine:

'domain' => 'localhost',

假设您已遵循Sanctum文档中的其余说明(设置 axios.defaults.withCredentials = true; ,添加中间件等),则您的后端配置现已完成.

Assuming you've followed the rest of the instructions in the Sanctum documentation (setting axios.defaults.withCredentials = true;, adding the middleware etc) your backend configuration is now complete.

前端和身份验证.

我爱圣所,并对创作者深表谢意;所以我很尊重地说在这一点上,文档还不够深入.抓住csrf令牌非常简单,然后...

I love Sanctum and I'm very grateful for the creators; so I say this with respect; the documentation lacks a little depth at this point. Grabbing the csrf-token is very straight forward, and then...

一旦CSRF保护已初始化,您应该向典型的Laravel/login路由发出POST请求.该/登录路径可以由laravel/jetstream身份验证支架包提供.如果登录请求成功,则将对您进行身份验证,并且随后通过Laravel后端发布给您的客户端的会话Cookie,对您对API路由的后续请求也将自动进行身份验证.

似乎他们已经更新了文档!在撰写本文时,我检查了最新文档,并着重强调了您可以自由编写自己的登录端点的事实.一直都是这种情况,但也许已经避开了几个人,也许是按照上述说明进行的(您应该向典型的Laravel/login路由发出POST请求.")也许还不清楚您是否可以覆盖默认的Laravel防止默认身份验证设置产生不良影响的方法,例如重定向到/home页面等.

It seems they've updated the docs! As I write this, I've checked the latest docs and it's now highlighted the fact that you are free to write your own login endpoint. This was always the case, but might have escaped a few people, perhaps given the instructions above ("you should make a POST request to the typical Laravel /login route.") It's also perhaps not clear that you can override default Laravel methods to prevent unwanted side-effects of the default auth setup, like redirecting to the /home page etc.

编写自己的登录控制器很简单,我更喜欢在Sanctum中这样做.这是您可以使用的一种:

Writing your own login controller is simple, and I prefer to do so for Sanctum. Here's one you can use:

<?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.'
    ]);

  }
}

可以随意修改此设置以满足您的需求.

Feel free to modify this to suit your needs.

如何管理前端的状态(例如,确保应用程序记住您已登录)也取决于您.有很多选择,但是,如果我们使用Sanctum,我认为我们应该专注于基于cookie的简单方法.这是我使用的一个:

How you manage your state (making sure your app remembers you are logged in, for example) on the front-end is also up to you. There are lots of options, however if we're using Sanctum I think we should focus on a simple cookie-based approach. Here's one I use:

  1. 登录到您的应用程序.建立身份验证会话,您的浏览器将保存您的Laravel API提供的cookie.
  2. 让您的登录脚本返回经过身份验证的用户(上面提供的身份就是这样).将该用户的详细信息保存到您的应用状态(例如Vuex).
  3. 在需要保护针对未经授权的用户的操作时,请检查您的状态是否包含该用户.重定向到登录页面是身份验证检查失败.

以下是使用中间件的Nuxt.js形式的内容.

Here's the above in Nuxt.js form using middleware.

/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
}

上面的代码是出于示例目的,但通常是我在Vue/Nuxt和Sanctum中使用的代码.

The code above is for example purposes, but it's generally what I use for Vue/Nuxt and Sanctum.

希望这会有所帮助,如果有人可以受益,我们很乐意进一步阐述.

Hope this helps, happy to elaborate further if anyone can benefit.

这篇关于如何将Laravel和Nuxtjs与Authentication一起使用,包括登录,注销和密码重置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆