未设置/存储Httponly cookie(Laravel / Vue)

问题描述 投票:0回答:1

我已经在这个问题上苦苦挣扎了几个小时,以解决这个问题,我似乎暂时无法解决。

正在构建具有Vue前端(使用vue-cli创建)和后端的Laravel 5.8(api)的简单身份验证系统;阅读this文章后,测试使用httponly cookie进行身份验证和保护对某些路由的访问的想法。我正在使用tymondesigns/jwt-auth进行身份验证,而不是本文中使用的laravel passport,并且还在使用barryvdh/laravel-cors 包添加CORS(跨源资源共享)标头支持。

BACKEND

这是我在routes/api.php中的代码

Route::group(['prefix' => 'auth', 'namespace' => 'Auth'], function () {
    Route::post('login', 'AuthController@login');

    Route::group(['middleware' => ['auth.api'],], function () {
        Route::get('me', 'AuthController@me');
        Route::post('logout', 'AuthController@logout');
    });
});

并且正在使用的中间件代码如下app/Http/Kernel.php中的>]

'auth.api' => [
    \App\Http\Middleware\AddAuthTokenHeader::class,
    'throttle:60,1',
    'bindings',
    'auth:api',
    \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
],

这是我在app/Http/Controllers/Auth/AuthController.php中的代码

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Requests\Auth\LoginRequest;

use App\Http\Controllers\Controller;

class AuthController extends Controller
{
    /**
     * Authenticate user via given credentials.
     *
     * @param \App\Http\Requests\Auth\LoginRequest $request
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function login(LoginRequest $request)
    {
        $credentials = $request->all(['email', 'password']);

        if (!$token = auth()->attempt($credentials)) {
            return response()->json(['error' => 'Invalid credentials'], 401);
        }

        $cookie = $this->getCookie($token);

        return response()->json([
            'token' => $token,
            'user' => auth()->user(),
        ])->withCookie($cookie);
    }

    /**
     * Set cookie details and return cookie
     *
     * @param string $token JWT
     *
     * @return \Illuminate\Cookie\CookieJar|\Symfony\Component\HttpFoundation\Cookie
     */
    private function getCookie($token)
    {
        return cookie(
            env('AUTH_COOKIE_NAME'),
            $token,
            auth()->factory()->getTTL(),
            null,
            null,
            env('APP_DEBUG') ? false : true,
            true,
            false,
            'Strict'
        );
    }

    public function logout()
    {
        // ...
    }

    public function me()
    {
        // ...
    }
}

并且自定义中间件app/Http/Middleware/AddAuthTokenHeader.php中使用的中间件类(auth.api)中handle方法的代码为

public function handle($request, Closure $next)
{
    $cookie_name = env('AUTH_COOKIE_NAME');

    if (!$request->bearerToken()) {
        if ($request->hasCookie($cookie_name)) {
            $token = $request->cookie($cookie_name);

            $request->headers->add([
                'Authorization' => 'Bearer ' . $token
            ]);
        }
    }

    return $next($request);
}

正如您在我的AuthController中看到的,一旦登录请求成功,则将json响应与仅HTTP cookie一起发送。

NOTE

:我正在使用php artisan serve运行我的后端

FRONT-END

在我的npm run serve生成的项目中运行vue-cli之后,转到login路径,该路径显示由Login表示的@/views/Login.vue组件。

这是我的Login.vue的代码

<template>
    <div>
        <form @submit.prevent="submit" autocomplete="off">
            <p>
                <label for="email">Email: </label>
                <input
                    type="email"
                    name="email"
                    id="email"
                    v-model.lazy="form.email"
                    required
                    autofocus
                />
            </p>
            <p>
                <label for="password">Password: </label>
                <input
                    type="password"
                    name="password"
                    id="password"
                    v-model.lazy="form.password"
                    required
                />
            </p>
            <button type="submit">Login</button>
        </form>
    </div>
</template>

<script>
import axios from 'axios';

export default {
    name: 'login',
    data() {
        return {
            form: {
                email: '',
                password: '',
            },
        };
    },

    methods: {
        async submit() {
            const url = 'http://localhost:8000/api/auth/login';
            const response = await axios.post(url, this.form, {
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'application/json',
                },
            });

            console.log(response);
            // this.$router.replace({ name: 'home' });
        },
    },
};
</script>

给出路由(http:localhost:8080/login)上的有效凭据,将返回Cookie,如下面的响应头所示

enter image description here

但是由于某些原因,未在浏览器cookie的cookie存储中进行设置,如下所示

enter image description here

NOTE

:上面显示的cookie是我测试的,它运行php artisan serve并在浏览器中打开http:localhost:8000后,是否一切运行正常。

问题是,为什么cookie不存储在浏览器cookie存储中。

[我应该注意,当我使用POSTMAN调用相同的后端api路由时,一切正常(在登录时设置cookie,并在注销时清除cookie)。

谢谢。

我已经在这个问题上苦苦挣扎了几个小时,以解决这个问题,但我似乎暂时无法解决。我正在使用Vue前端构建一个简单的身份验证系统...

laravel vue.js cookies laravel-5.8
1个回答
0
投票

感谢@skirtle帮我解决了这个问题;您的帮助非常宝贵。

© www.soinside.com 2019 - 2024. All rights reserved.