Vue 구축Laravel Sanctum의 js 클라이언트 SPA 영패 인증 사용

46461 단어 vuelaravelauthsanctum
인증 시스템은 대부분의 현대 응용 프로그램의 중요한 구성 부분이기 때문에 적절하게 실시해야 한다.
본고에서 Vue.jsLaravel Sanctum(이전의 Airlock)을 사용하여 인증 시스템을 구축하는 방법을 배울 것입니다.
우리는 RESTAPI를 통해 상호 작용하는 프런트엔드와 백엔드를 위한 별도의 프로젝트를 만들 것입니다.
우리 잠수하자!

백엔드(Laravel)


단계 #1


Laravel 설치 지침은 Official Documentation페이지를 참조하십시오.
터미널에서 실행하여 새 Laravel 항목 만들기
laravel new my-app
또는
composer create-project --prefer-dist laravel/laravel my-app
저는 Laravel Valet을 사용하고 있습니다. 이것은 자동으로 http://my-app.test 도메인의 사이트를 방문할 수 있도록 합니다.
당신의 기계에서, 그것은 당신의 현지 개발 환경 설정에 따라 접근할 것입니다.

단계 #2

my-app이라는 새 데이터베이스를 만들고 응용 프로그램 디렉터리에 있는 DB_DATABASE=my-app 파일에 .env을 설정합니다.

단계 #3


Laravel Sanctum을 설치합니다.
composer require laravel/sanctum
vendor:publish Artisan 명령을 사용하여 Sanctum 구성 및 마이그레이션 파일을 게시합니다.sanctum 구성 파일은 config 디렉토리에 배치됩니다.
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
데이터베이스 마이그레이션을 실행하여 API 토큰을 저장하는 데이터베이스 테이블을 만듭니다.
php artisan migrate
응용 프로그램/Http/Kernel의 api 중간부품 그룹에 Sanctum의 중간부품을 추가합니다.php
../app/Http/Kernel.php

use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;

...

    protected $middlewareGroups = [
        ...

        'api' => [
            EnsureFrontendRequestsAreStateful::class,
            'throttle:60,1',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];

    ...
],

4단계


사용자를 위해 영패를 사용하려면 HasApiTokens을 응용 프로그램/사용자의 User 모델에 추가해야 합니다.php.
../app/User.php

use Laravel\Sanctum\HasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

단계 #5

User 모형을 위해 파종기를 만듭니다.잠시 후 로그인 과정을 테스트할 필요가 있습니다.
php artisan make:seeder UsersTableSeeder
지금 꽂아달래요.
DB::table('users')->insert([
    'name' => 'John Doe',
    'email' => '[email protected]',
    'password' => Hash::make('password')
]);
데이터베이스/seeds/userstableseder의 run() 함수에 들어갑니다.php
user를 users 테이블 피드로 사용하려면 다음을 실행하십시오.
php artisan db:seed --class=UsersTableSeeder
현재 데이터베이스에 John Doe, 전자 우편 [email protected], 비밀번호 password이라는 새로운 사용자가 있습니다.

단계 #6


루트/api에서 /login 루트를 만듭니다.php 파일:
../routes/api.php

use App\User;
use Illuminate\Support\Facades\Hash;

Route::post('/login', function (Request $request) {
    $data = $request->validate([
        'email' => 'required|email',
        'password' => 'required'
    ]);

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

    if (!$user || !Hash::check($request->password, $user->password)) {
        return response([
            'message' => ['These credentials do not match our records.']
        ], 404);
    }

    $token = $user->createToken('my-app-token')->plainTextToken;

    $response = [
        'user' => $user,
        'token' => $token
    ];

    return response($response, 201);
});

7단계


이메일 [email protected]과 암호 password을 매개 변수로 http://my-app.test/api/login 라우팅하는 POST 요청을 보냅니다.당신은 Postman 또는 Insomnia 소프트웨어 패키지를 사용하여 이 점을 실현할 수 있습니다.
만약 모든 것이 정상이라면, 우리는 우리의 요청에 대한 응답으로 JSON 대상을 받을 것이다.
{
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "[email protected]",
        "email_verified_at": null,
        "created_at": null,
        "updated_at": null
    },
    "token": "AbQzDgXa..."
}

단계 #8


다음으로, 우리는 일부 중간부품을 변경해야 한다.우리는/routes/api에서 이 동작을 실행합니다.auth:apiauth:sanctum의 php 파일로 바꿉니다.
../routes/api.php

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

9단계


프런트엔드를 계속하기 전에, 우리는 원점 간 요청 CORS 처리를 설정해야 한다.
../config/cors.php

    'paths' => ['api/*', 'login', 'logout'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,
../.env

SANCTUM_STATEFUL_DOMAINS=127.0.0.1

프런트엔드(Vue.js)


우리는 Vuex을 사용하여 상태 관리를 하고 Vue Router을 루트로 하며 axios을 사용하여 HTTP 요청을 할 것이다.

단계 #1


Vue CLI을 사용하여 새 Vue 프로젝트를 만듭니다.Vue의 표준 도구에 익숙하지 않은 경우js개발, 이 guide을 읽어 주십시오.
프로젝트에 사용되는 디렉토리에서 다음 명령을 실행합니다.
vue create my-vue-app
Manually select features 선택 후 RouterVuex 선택
my-vue-app 프로젝트를 성공적으로 작성한 후 다음 명령을 실행합니다.
cd my-vue-app
npm run serve
현재 우리의 응용 프로그램은 http://localhost:8080/ 도메인 이름에서 사용할 수 있을 것이다.

단계 #2

Login 보기에 새 파일을 만듭니다.
..src/views/Login.vue

<template>
  <div>
    <h1>Login</h1>
    <form @submit.prevent="login">
      <input type="email" name="email" v-model="email">
      <input type="password" name="password" v-model="password">
      <button type="submit">Login</button>
    </form>
  </div>
</template>

<script>
export default {
  data () {
    return {
      email: '',
      password: ''
    }
  },

  methods: {
    login () {
      this.$store
        .dispatch('login', {
          email: this.email,
          password: this.password
        })
        .then(() => {
          this.$router.push({ name: 'About' })
        })
        .catch(err => {
          console.log(err)
        })
    }
  }
}
</script>
Vue Router에서 우리는 Login보기의 경로를 실현해야 한다.
../src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "login" */ '../views/Login.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

현재 브라우저에서 http://localhost:8080/login을 탐색하면 로그인 페이지를 볼 수 있습니다.

단계 #3


HTTP 요청은 프런트엔드 디렉토리에 axios을 설치해야 합니다.
npm install axios

4단계


Vuex에서 사용자 인증 작업 (login/logout)을 수행합니다.
../src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'

Vue.use(Vuex)

axios.defaults.baseURL = 'http://app-backend.test/api'

export default new Vuex.Store({
  state: {
    user: null
  },

  mutations: {
    setUserData (state, userData) {
      state.user = userData
      localStorage.setItem('user', JSON.stringify(userData))
      axios.defaults.headers.common.Authorization = `Bearer ${userData.token}`
    },

    clearUserData () {
      localStorage.removeItem('user')
      location.reload()
    }
  },

  actions: {
    login ({ commit }, credentials) {
      return axios
        .post('/login', credentials)
        .then(({ data }) => {
          commit('setUserData', data)
        })
    },

    logout ({ commit }) {
      commit('clearUserData')
    }
  },

  getters : {
    isLogged: state => !!state.user
  }
})

로그인에 성공하면 user 변수와 localStorage에 사용자 데이터를 저장합니다.

단계 #5


인증되지 않은 페이지와 인증되지 않은 페이지의 경로를 정의합니다.
우리는 About 페이지를 인증을 받은 사용자에게만 접근할 수 있도록 할 수 있습니다.
이를 위해 meta 필드를 About 라우트에 추가합니다.
Vue Router의 beforeEach 메서드를 사용하여 사용자의 로그인 여부를 확인합니다.만약 사용자가 인증을 거치지 않았다면, 우리는 그것을 다시 로그인 페이지로 정할 것입니다.
../src/router.index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    meta: {
      auth: true
    },
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "login" */ '../views/Login.vue')
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

router.beforeEach((to, from, next) => {
  const loggedIn = localStorage.getItem('user')

  if (to.matched.some(record => record.meta.auth) && !loggedIn) {
    next('/login')
    return
  }
  next()
})

export default router

단계 #6


사용자가 페이지를 새로 고치면 어떻게 됩니까?우리는 반드시 그를 다시 로그인하게 해야 합니까?
당연히 아니지!created() 실례에 Vue 방법을 추가하여 이 장면을 처리합시다.
created () {
  const userInfo = localStorage.getItem('user')
  if (userInfo) {
    const userData = JSON.parse(userInfo)
    this.$store.commit('setUserData', userData)
  }
}

7단계


우리는 영패가 기한이 지났거나 사용자가 권한을 부여받지 않은 상황을 처리해야 한다.created() 방법에서 차단기를 사용하여 이 점을 실현합시다.
따라서 업데이트된 main.js 파일은 다음과 같습니다.
../src/main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  created () {
    const userInfo = localStorage.getItem('user')
    if (userInfo) {
      const userData = JSON.parse(userInfo)
      this.$store.commit('setUserData', userData)
    }
    axios.interceptors.response.use(
      response => response,
      error => {
        if (error.response.status === 401) {
          this.$store.dispatch('logout')
        }
        return Promise.reject(error)
      }
    )
  },
  render: h => h(App)
}).$mount('#app')

단계 #8


우리는 아직 Logout의 특성을 실현하지 못했다.App.vue 파일에서 이렇게 합시다.
또한 사용자가 로그인할 때만 AboutLogout 버튼을 표시합니다.
../src/App.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about" v-if="isLogged">About</router-link>
      <router-link to="/login" v-else>Login</router-link>
      <button type="button" @click="logout()" v-if="isLogged">
        Logout
      </button>
    </div>
    <router-view/>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters([
      'isLogged'
    ])
  },

  methods: {
    logout () {
      this.$store.dispatch('logout')
    }
  }
}
</script>
자, 우리 강좌가 끝났습니다.
나는 네가 이 정보를 발견하는 것이 도움이 되기를 바란다.
소스 코드 보기
Front End
Back End

좋은 웹페이지 즐겨찾기