programing

Laravel Passport 미들웨어 보호 경로 "인증되지 않음" 문제

prostudy 2022. 5. 20. 21:33
반응형

Laravel Passport 미들웨어 보호 경로 "인증되지 않음" 문제

나는 인증을 위해 Laravel Passport를 사용하고 있어서 미들웨어 보호에 내 루트를 넣었어.

업데이트됨

확실히 하기 위해 UsersController도 추가한다.

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

//

Route::group(['prefix' => 'v1', 'middleware' => 'auth:api'], function () {
    /* users */
    Route::get('/users', 'Api\UsersController@getUser');

    /* fetch */
    Route::get('/articles', 'Api\ArticlesController@allArticles');
    Route::get('/article/{id}', 'Api\ArticlesController@singleArticle');
});

물론 로그인이 필요하거나 보호 경로가 보이지 않는다.나는 만들었다.AuthController그리고 그 안에는 컨트롤러 로그인 기능이 있다.

제어기

public function login(Request $request)
{
    $http = new \GuzzleHttp\Client;
    try {
        $response = $http->post(config('services.passport.login_endpoint'), [
            'form_params' => [
                'grant_type' => 'password',
                'client_id' => config('services.passport.client_id'),
                'client_secret' => config('services.passport.client_secret'),
                'username' => $request->email,
                'password' => $request->password,
            ]
        ]);
        return $response->getBody();
    } catch (\GuzzleHttp\Exception\BadResponseException $e) {
        if ($e->getCode() === 400) {
            return response()->json('Invalid Request. Please enter a username or a password.', $e->getCode());
        }

        if ($e->getCode() === 401) {
            return response()->json('Your credentials are incorrect. Please try again', $e->getCode());
        }

        return response()->json('Something went wrong on the server.', $e->getCode());
    }
}

내 술집의 앞쪽 끝에는 액션 콜이 있다.

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는 로그인한 사용자를 모른다.

토큰을 머리글에 어디에 넣어야 할까?컨트롤러 내부 또는 로그인 방법?아니면 다른 일을 해야 하나?

또한 인증자만 볼 수 있는 로그인한 사용자 보기 페이지.

어떻게 이게 가능하죠?사용자가 auth 사용자가 볼 수 있는 것을 볼 수 있는 경우, 이는 사용자가 다음을 만들고 있음을 의미한다.GET인증 토큰으로 요청하시겠습니까?여권을 사용하는 경우, 승인 헤더에 토큰을 넣으십시오.

axios.defaults.headers.common.Authorization = `Bearer ${token}`;

로그인한 후 모든 공리 요청에 토큰을 삽입하려면 이 옵션을 사용하십시오. 그러면 바로 가십시오.

로그인 구성 요소 사용 시

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 경로를 정의하십시오.

만약 당신이 javascript와 함께 당신의 api를 소비하고 있다면 나는 그것을 추가하는 것을 제안할 것이다.CreateFreshApiToken웹 미들웨어 그룹에 미들웨어.

문서에서:

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

그렇지 않은 경우, 다른 사용자가 언급한 대로 권한 부여 헤더와 내용 유형 헤더를 요청에 포함시키십시오.

임의의 클라이언트 호출에 대해 항상 토큰에 의한 인증을 사용하는 경우 인증 헤더를 설정했는지 확인하십시오.Authorization = Bearer your_token보호 경로에 대해 클라이언트에서 호출할 때라라벨 패스포트와 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);
        }

나의 사랑스런 길,'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');
    });

});

나의guardsconfig/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.defaults.headers.common.Authorization = 'Bearer ${state.token}';.

참조URL: https://stackoverflow.com/questions/56590953/laravel-passport-middleware-protected-routes-unauthenticated-problem

반응형