laravel vue实现登录
Laravel 和 Vue.js 实现登录功能
后端配置(Laravel)
安装 Laravel Sanctum 用于 API 认证
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
在 config/auth.php 中设置 API 守卫
'guards' => [
'api' => [
'driver' => 'sanctum',
'provider' => 'users',
],
],
创建登录路由(routes/api.php)
use App\Http\Controllers\AuthController;
Route::post('/login', [AuthController::class, 'login']);
创建 AuthController
php artisan make:controller AuthController
实现登录逻辑(app/Http/Controllers/AuthController.php)
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$token = $user->createToken('auth_token')->plainTextToken;
return response()->json([
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
return response()->json(['error' => 'Invalid credentials'], 401);
}
前端配置(Vue.js)
安装 Axios 进行 HTTP 请求
npm install axios
创建登录组件(resources/js/components/Login.vue)
<template>
<div>
<input v-model="email" type="email" placeholder="Email">
<input v-model="password" type="password" placeholder="Password">
<button @click="login">Login</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
email: '',
password: ''
}
},
methods: {
async login() {
try {
const response = await axios.post('/api/login', {
email: this.email,
password: this.password
});
localStorage.setItem('auth_token', response.data.access_token);
axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.access_token}`;
this.$router.push('/dashboard');
} catch (error) {
console.error('Login failed:', error.response.data);
}
}
}
}
</script>
配置 Axios 默认设置(resources/js/app.js)
import axios from 'axios';
window.axios = axios;
const token = localStorage.getItem('auth_token');
if (token) {
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
}
保护路由
创建中间件来验证 API 请求(app/Http/Middleware/AuthenticateAPI.php)
public function handle($request, Closure $next)
{
if (!Auth::guard('sanctum')->check()) {
return response()->json(['message' => 'Unauthorized'], 401);
}
return $next($request);
}
在 Kernel.php 中注册中间件
protected $routeMiddleware = [
'auth.api' => \App\Http\Middleware\AuthenticateAPI::class,
];
保护路由(routes/api.php)
Route::middleware('auth.api')->group(function () {
Route::get('/user', function () {
return Auth::user();
});
});
Vue 路由保护
创建路由守卫(resources/js/router/index.js)
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!localStorage.getItem('auth_token')) {
next({ path: '/login' });
} else {
next();
}
} else {
next();
}
});
标记需要认证的路由
{
path: '/dashboard',
component: Dashboard,
meta: { requiresAuth: true }
}
注销功能
后端路由(routes/api.php)
Route::post('/logout', [AuthController::class, 'logout']);
实现注销方法(AuthController.php)
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out']);
}
前端注销按钮(Dashboard.vue)
<button @click="logout">Logout</button>
methods: {
async logout() {
await axios.post('/api/logout');
localStorage.removeItem('auth_token');
delete axios.defaults.headers.common['Authorization'];
this.$router.push('/login');
}
}
跨域配置
在 config/cors.php 中配置
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:8080'],
'allowed_headers' => ['*'],
在 .env 中设置会话域
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8080






