Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Laravel Passport“受保护的路线”;“未经验证的”;问题_Laravel_Vue.js_Laravel 5_Vuejs2_Laravel Passport - Fatal编程技术网

Laravel Passport“受保护的路线”;“未经验证的”;问题

Laravel Passport“受保护的路线”;“未经验证的”;问题,laravel,vue.js,laravel-5,vuejs2,laravel-passport,Laravel,Vue.js,Laravel 5,Vuejs2,Laravel Passport,我使用Laravel Passport进行身份验证,因此我将我的路由置于中间件保护中 更新 为了清楚起见,我还添加了UsersController public function getUser() { $users = Auth::user(); return response()->json($users); } // Route::group(['prefix'=>'v1','middleware'=>'auth:api'],函数(){ /*使用者*/ 路由::获取

我使用Laravel Passport进行身份验证,因此我将我的路由置于中间件保护中

更新 为了清楚起见,我还添加了UsersController

public function getUser()
{
    $users = Auth::user();
    return response()->json($users);
}
//

Route::group(['prefix'=>'v1','middleware'=>'auth:api'],函数(){
/*使用者*/
路由::获取('/users',Api\UsersController@getUser');
/*取回*/
路由::获取('/articles',Api\ArticlesController@allArticles');
路由::get('/article/{id}',Api\ArticlesController@singleArticle');
});
当然,我需要登录,否则我看不到受保护的路由。我做了一个
AuthController
,里面有一个controller登录函数

控制器

公共功能登录(请求$Request)
{
$http=new\GuzzleHttp\Client;
试一试{
$response=$http->post(配置('services.passport.login\u endpoint')[
“表单参数”=>[
“授权类型”=>“密码”,
'client_id'=>config('services.passport.client_id'),
'client_secret'=>config('services.passport.client_secret'),
“用户名”=>$request->email,
“密码”=>$request->password,
]
]);
返回$response->getBody();
}捕获(\GuzzleHttp\Exception\BadResponseException$e){
如果($e->getCode()==400){
return response()->json('请求无效。请输入用户名或密码',$e->getCode());
}
如果($e->getCode()==401){
return response()->json('您的凭据不正确,请重试',$e->getCode());
}
return response()->json('服务器出现问题',$e->getCode());
}
}
在vuex的前端,我有一个行动电话

retrieveToken(context, credentials){
    return new Promise((resolve, reject) => {
            axios.post("api/v1/login", {
                email: credentials.username,
                password: credentials.password,
            })
            .then(response => {
                const token = response.data.access_token;
                localStorage.setItem("access_token", token);
                context.commit("retrieveToken", token);
                resolve(resolve);
            })
            .catch(error => {
                console.log(error);
                reject(response);
            })
    })
},
一切都很好。我存储令牌并将其用于登录,然后在注销时将其删除。但在后端,缺少了一些东西。因为即使登录,我仍然看不到受保护的路由。Laravel的身份验证不知道该用户已登录

我应该把代币放在哪里?控制器内部还是登录方法?还是我需要做点别的

此外,登录的用户可以看到只有身份验证用户才能看到的页面

你是怎么做到的?如果用户可以看到auth user可以看到的内容,这意味着您正在使用auth令牌发出
GET
请求,对吗?如果您使用的是passport,则应将令牌放入授权标头中

axios.defaults.headers.common.Authorization = `Bearer ${token}`;
登录后,使用此选项将令牌放入您的all axios请求中,然后您就可以开始了。

在登录组件中使用

methods: {
    login() {
      var instance = axios.create({
        baseURL: "http://apiendpoint.com/api/"
      });

      instance
        .post("/admin-login", {
          email: this.username,
          password: this.password,
          device_type: "Web",
          device_token: "Web"
        })
        .then(response => {
          // console.log(response);

          localStorage.setItem("token", response.data.data.token);
          this.$router.push("/");
        })
        .catch(error => {
          console.log(error);
        });
    }
  },
然后将文件中的axios配置定义为Repository.js,该文件可用于所有资源

/******************** Repository js ****************/
import axios from "axios";
import router from "./router";

const baseDomain = "http://apiendpoint.com/api/";
const baseURL = `${baseDomain}/api`;

const api = axios.create({
    baseURL, // headers: {
    //  'Authorization': 'Bearer ' + localStorage.getItem('api_token')
    // },
    validateStatus: function(status) {
        if (status == 401) {
            router.push("/login");
        } else {
            return status;
        }
    }
});
api.interceptors.request.use(
    function(config) {
        const token = localStorage.getItem("token");

        if (token == null) {
            console.log("Token Is empty");
            console.log("Redirecting to Login");
            router.push({ name: "login" });
        }

        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    function(response) {
        return response;
        console.log(response);
    },
    function(error) {
        console.log(error);

        return error;
    }
);
// Add a response interceptor
api.interceptors.response.use(
    function(response) {
        // Do something with response data
        return response;
    },
    function(error) {
        // Do something with response error
        console.log("Error Found");

        return Promise.reject(error);
    }
);
export default api;
并定义路由器中的所有vue路由。

如果您只是简单地选择,我建议将
CreateFreshApiToken
中间件添加到您的web中间件组中

来自文档:

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

否则,如其他人所述,请确保在您的请求中包含授权标头和内容类型标头。

如果您在laravel passport中使用令牌身份验证,请始终确保为受保护的路由设置身份验证标头(对于任何客户端呼叫)
Authorization=Bearer\u令牌
,当从客户端调用它时。我用Laravel Passport和Vue.js制作了一个简单的身份验证示例,并将其上传到github,请查看。我还建议您阅读

您在Laravel中的登录应该如下所示

 public function login (Request $request) {

        $user = User::where('email', $request->email)->first();

        if ($user) {

            if (Hash::check($request->password, $user->password)) {
                $token = $user->createToken('Laravel Password Grant Client')->accessToken;
                $response = ['token' => $token];
                return response($response, 200);
            } else {
                $response = "Password missmatch";
                return response($response, 422);
            }

        } else {
            $response = 'User does not exist';
            return response($response, 422);
        }
我的laravel路由,
'middleware'=>['json.response']
,我使用json强制所有数据

Route::group(['middleware' => ['json.response']], function () {

    Route::middleware('auth:api')->get('/user', function (Request $request) {
        return $request->user();
    });

    // public routes
    Route::post('/login', 'Api\AuthController@login')->name('login.api');
    Route::post('/register', 'Api\AuthController@register')->name('register.api');

    // private routes
    Route::middleware('auth:api')->group(function () {
        Route::get('/logout', 'Api\AuthController@logout')->name('logout');
    });

});
config/auth.php

  'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
    ],
然后在vue中,您可以使用vuex存储令牌,并使用用户数据重复使用它
store/index.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
    strict: debug,
    state: {
        auth: null,
        token: null,
        check:false
    },
    getters: {
        auth: state => state.auth,
        token: state => state.token,
    },
    mutations: {
        SET_TOKEN(state, token) {
            state.token = token
        },

        FETCH_auth_SUCCESS(state, auth) {
            state.auth = auth
            state.check = true
        },

        FETCH_auth_FAILURE(state) {
            state.token = null
        },

        LOGOUT(state) {
            state.auth = null
            state.token = null
            state.check = false
        },

        UPDATE_auth(state, { auth }) {
            state.auth = auth
        }
    },

    actions: {
        saveToken({ commit, dispatch }, { token, remember }) {
            commit('SET_TOKEN', token)

            // if you need store token in cookie (remember me option)
            // Cookies.set('token', token, { expires: remember ? 365 : null })
        },

        async fetchauth({ commit,state }) {
            try {
                axios.defaults.headers.common.Authorization = `Bearer ${state.token}`;
                const { data } = await axios.get('/api/user')

                commit('FETCH_auth_SUCCESS', data)
            } catch (e) {
                //   Cookies.remove('token')
                commit('FETCH_auth_FAILURE')
            }
        },

        updateauth({ commit }, payload) {
            commit('UPDATE_auth', payload)
        },

        async logout({ commit,state }) {
            try {
                axios.defaults.headers.common.Authorization = `Bearer ${state.token}`;
                await axios.get('/api/logout')
            } catch (e) {console.log(e) }

            // Cookies.remove('token')
            commit('LOGOUT')
        },
    }
});
注意我设置了令牌
axios.defaults.headers.common.Authorization='Bearer${state.token}',但您可以全局执行一次

vue中的登录方法

 methods: {
    login() {
      console.log("Login");
      axios
        .post("/api/login", {
          email: this.form.email,
          password: this.form.password
        })
        .then(res => {
          // save token to vuex
          this.$store.dispatch("saveToken", { token: res.data.token });
          // get user data, store in vuex
          this.$store.dispatch("fetchauth");
          // redirect
          this.$router.push({path:'/dashboard'});
        })
        .catch(e => {
          console.log(e);
        });
    }
  }

当您通过
'auth:api'
调用受保护的路由时,首先需要在头中设置令牌以访问资源。在axios中是
axios.defaults.headers.common.Authorization='Bearer${state.token}'

我试图将其放入
fetchToken()
的内部然后
。然后()
部分,但仍然会弹出相同的错误。尝试检查您的标题,是否有
授权
标题?当我登录时,但是当我刷新页面时,它就消失了。那么,当你加载应用程序时,你是否将令牌放入了标题中?我保存了令牌localStorage。当我获取文章或用户时,使用该标记(放在标题上)。。。比如像这样。我可以在控制台上看到json的预览。但在浏览器上看不到端点,它表示您必须登录@NipunTharuksha将我重定向到登录页面请从retrieveToken函数内部共享
控制台.log(响应)
的输出。