瀏覽代碼

新增 login logout

oransheep 2 年之前
父節點
當前提交
b98bb78a16

+ 1 - 1
database/seeders/DatabaseSeeder.php

@@ -14,6 +14,6 @@ class DatabaseSeeder extends Seeder
      */
     public function run()
     {
-        // \App\Models\User::factory(10)->create();
+        \App\Models\User::factory(3)->create();
     }
 }

+ 2 - 2
resources/js/src/@core/auth/jwt/jwtDefaultConfig.js

@@ -1,9 +1,9 @@
 export default {
   // Endpoints
-  loginEndpoint: '/jwt/login',
+  loginEndpoint: '/api/login',
   registerEndpoint: '/jwt/register',
   refreshEndpoint: '/jwt/refresh-token',
-  logoutEndpoint: '/jwt/logout',
+  logoutEndpoint: '/api/logout',
 
   // This will be prefixed in authorization header with token
   // e.g. Authorization: Bearer <token>

+ 4 - 0
resources/js/src/@core/auth/jwt/jwtService.js

@@ -99,6 +99,10 @@ export default class JwtService {
     return this.axiosIns.post(this.jwtConfig.loginEndpoint, ...args)
   }
 
+  logout() {
+    return this.axiosIns.post(this.jwtConfig.logoutEndpoint)
+  }
+
   register(...args) {
     return this.axiosIns.post(this.jwtConfig.registerEndpoint, ...args)
   }

+ 22 - 48
resources/js/src/layouts/components/Navbar.vue

@@ -4,14 +4,8 @@
     <!-- Nav Menu Toggler -->
     <ul class="nav navbar-nav d-xl-none">
       <li class="nav-item">
-        <b-link
-          class="nav-link"
-          @click="toggleVerticalMenuActive"
-        >
-          <feather-icon
-            icon="MenuIcon"
-            size="21"
-          />
+        <b-link class="nav-link" @click="toggleVerticalMenuActive">
+          <feather-icon icon="MenuIcon" size="21" />
         </b-link>
       </li>
     </ul>
@@ -22,11 +16,7 @@
     </div>
 
     <b-navbar-nav class="nav align-items-center ml-auto">
-      <b-nav-item-dropdown
-        right
-        toggle-class="d-flex align-items-center dropdown-user-link"
-        class="dropdown-user"
-      >
+      <b-nav-item-dropdown right toggle-class="d-flex align-items-center dropdown-user-link" class="dropdown-user">
         <template #button-content>
           <div class="d-sm-flex d-none user-nav">
             <p class="user-name font-weight-bolder mb-0">
@@ -34,60 +24,34 @@
             </p>
             <span class="user-status">Admin</span>
           </div>
-          <b-avatar
-            size="40"
-            variant="light-primary"
-            badge
-            :src="require('@/assets/images/avatars/13-small.png')"
-            class="badge-minimal"
-            badge-variant="success"
-          />
+          <b-avatar size="40" variant="light-primary" badge :src="require('@/assets/images/avatars/13-small.png')"
+            class="badge-minimal" badge-variant="success" />
         </template>
 
         <b-dropdown-item link-class="d-flex align-items-center">
-          <feather-icon
-            size="16"
-            icon="UserIcon"
-            class="mr-50"
-          />
+          <feather-icon size="16" icon="UserIcon" class="mr-50" />
           <span>Profile</span>
         </b-dropdown-item>
 
         <b-dropdown-item link-class="d-flex align-items-center">
-          <feather-icon
-            size="16"
-            icon="MailIcon"
-            class="mr-50"
-          />
+          <feather-icon size="16" icon="MailIcon" class="mr-50" />
           <span>Inbox</span>
         </b-dropdown-item>
 
         <b-dropdown-item link-class="d-flex align-items-center">
-          <feather-icon
-            size="16"
-            icon="CheckSquareIcon"
-            class="mr-50"
-          />
+          <feather-icon size="16" icon="CheckSquareIcon" class="mr-50" />
           <span>Task</span>
         </b-dropdown-item>
 
         <b-dropdown-item link-class="d-flex align-items-center">
-          <feather-icon
-            size="16"
-            icon="MessageSquareIcon"
-            class="mr-50"
-          />
+          <feather-icon size="16" icon="MessageSquareIcon" class="mr-50" />
           <span>Chat</span>
         </b-dropdown-item>
 
         <b-dropdown-divider />
 
-        <b-dropdown-item link-class="d-flex align-items-center">
-          <feather-icon
-            size="16"
-            icon="LogOutIcon"
-            class="mr-50"
-          />
+        <b-dropdown-item link-class="d-flex align-items-center" @click="logout">
+          <feather-icon size="16" icon="LogOutIcon" class="mr-50" />
           <span>Logout</span>
         </b-dropdown-item>
       </b-nav-item-dropdown>
@@ -100,6 +64,7 @@ import {
   BLink, BNavbarNav, BNavItemDropdown, BDropdownItem, BDropdownDivider, BAvatar,
 } from 'bootstrap-vue'
 import DarkToggler from '@core/layouts/components/app-navbar/components/DarkToggler.vue'
+import useJwt from '@/auth/jwt/useJwt'
 
 export default {
   components: {
@@ -116,7 +81,16 @@ export default {
   props: {
     toggleVerticalMenuActive: {
       type: Function,
-      default: () => {},
+      default: () => { },
+    },
+  },
+  methods: {
+    logout() {
+      useJwt.logout()
+        // eslint-disable-next-line no-unused-vars
+        .then(res => {
+          this.$router.push({ path: '/login' })
+        })
     },
   },
 }

+ 10 - 0
resources/js/src/views/Login.vue

@@ -65,6 +65,7 @@
                 >
                   <b-form-input
                     id="login-email"
+                    ref="inputEmail"
                     v-model="userEmail"
                     :state="errors.length > 0 ? false:null"
                     name="login-email"
@@ -93,6 +94,7 @@
                   >
                     <b-form-input
                       id="login-password"
+                      ref="inputPassword"
                       v-model="password"
                       :state="errors.length > 0 ? false:null"
                       class="form-control-merge"
@@ -194,6 +196,7 @@ import { required, email } from '@validations'
 import { togglePasswordVisibility } from '@core/mixins/ui/forms'
 import store from '@/store/index'
 import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
+import useJwt from '@/auth/jwt/useJwt'
 
 export default {
   components: {
@@ -251,6 +254,13 @@ export default {
               variant: 'success',
             },
           })
+
+          useJwt.login({ email: this.$refs.inputEmail.value, password: this.$refs.inputPassword.value })
+            .then(res => {
+              useJwt.setToken(res.data.token)
+              localStorage.setItem('userData', res.data.userData)
+              this.$router.push({ path: '/' })
+            })
         }
       })
     },

+ 31 - 0
routes/api.php

@@ -2,6 +2,10 @@
 
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Route;
+use Illuminate\Support\Facades\Hash;
+use Illuminate\Validation\ValidationException;
+
+use App\Models\User;
 
 /*
 |--------------------------------------------------------------------------
@@ -17,3 +21,30 @@ use Illuminate\Support\Facades\Route;
 Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
     return $request->user();
 });
+
+Route::post('/login', function (Request $request) {
+    $request->validate([
+        'email' => 'required|email',
+        'password' => 'required',
+    ]);
+ 
+    $user = User::where('email', $request->email)->first();
+ 
+    if (! $user || ! Hash::check($request->password, $user->password)) {
+        throw ValidationException::withMessages([
+            'email' => ['The provided credentials are incorrect.'],
+        ]);
+    }
+
+    return [
+        'token' => $user->createToken('login')->plainTextToken,
+        'userData' => json_encode($user)
+    ];
+});
+
+Route::middleware('auth:sanctum')->post('/logout', function (Request $request) {
+    $user = $request->user();
+    // $user->tokens()->delete();
+    $user->tokens()->where('tokenable_id', $user->id)->delete();
+    return $user;
+});