记 Laravel Sanctum 实现 token登录
记 Laravel Sanctum 实现 token登录
-
假设已经安装好 Laravel
-
安装 Laravel Sanctum.
composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate
-
修改
../app/Http/Kernel.php
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful; ... protected $middlewareGroups = [ ... 'api' => [ EnsureFrontendRequestsAreStateful::class, 'throttle:60,1', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; ... ],
-
修改
../app/User.php
use Laravel\Sanctum\HasApiTokens; class User extends Authenticatable { use HasApiTokens, Notifiable; }
-
创建用户
php artisan make:seeder UsersTableSeeder DB::table('users')->insert([ 'name' => 'John Doe', 'email' => 'john@doe.com', 'password' => Hash::make('password') ]); // into the run() function in database/seeds/UsersTableSeeder.php // To seed users table with user, let's run: php artisan db:seed --class=UsersTableSeeder
-
在
routes/api.php
创建 路由/login
// ../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); });
-
在 /routes/api.php 文件中把
auth:api
替换成auth:sanctum
// ../routes/api.php Route::middleware('auth:sanctum')->get('/user', function (Request $request) { return $request->user(); });
-
修改
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
请求时加上Authorization
头// route/index.js import { createRouter, createWebHashHistory } from "vue-router" import store from '../store.ts' const routes = [ { path: '/', component: () => import('@/components/AdminIndex.vue') },{ path: '/admin', component: () => import('@/components/AdminIndex.vue') },{ path: '/login', component: () => import('@/components/AdminLogin.vue') }, ] if (sessionStorage.getItem("token")){ store.commit("set_token", sessionStorage.getItem("token")) } export const router = createRouter({ history: createWebHashHistory(), routes: routes }) export default router
// store.ts import { createStore } from 'vuex'; export default createStore({ state: { token: '' }, getters: {}, mutations: { set_token(state, token) { state.token = token; sessionStorage.token = token } }, actions: {}, modules: {} });
// main.js import { createApp } from 'vue' import App from './App.vue' import Antd from 'ant-design-vue'; import router from './router/index' import VueCookies from 'vue3-cookies' import store from './store.ts' // import 'ant-design-vue/dist/antd.css'; import VueLazyload from 'vue-lazyload' import axios from "axios"; // 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求前的操作 // 判断是否存在token,如果存在将每个页面header添加token if (store.state.token) { console.log(store.state.token) // config.headers.common['Authorization'] = "Bearer " + store.state.token config.headers.Authorization = "Bearer " + store.state.token } return config }, function (error) { router.push('/') return Promise.reject(error) }) // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 操作相应数据 return response }, function (error) { // 响应错误后做什么(可自由发挥) if (error.response) { switch (error.response.status) { case 401: store.commit('del_token') router.push('/') } } return Promise.reject(error) }) const app = createApp(App); // 创建App app.use(VueLazyload) app.use(router) app.use(store) app.use(VueCookies) app.use(Antd).mount('#app');
// AdminIndex.vue <script setup> const store = useStore(); const {proxy} = getCurrentInstance() const loginAdmin = (data) => { console.log(data) if (data['status']==="success") { message.success('登录成功!'); // 设置cookie store.commit("set_token", data['token']['plainTextToken']); // get_data() loginCheck.value = "true" // 'plainTextToken' } else { message.error('登录失败,请检查账号密码重试'); } } </script>
-
上面的方法不太好使,还是大佬写的源码吧
// vue 界面判断是否登录 import { createRouter, createWebHashHistory } from "vue-router" import store from '../store.ts' onMounted(()=>{ // 获取cookie const token = localStorage.getItem('token') if (token) { store.commit("set_token", token); loginCheck.value = true } }
// store.ts import { createStore } from 'vuex'; import axios from 'axios' export default createStore({ state: { token: '' }, getters: {}, mutations: { set_token(state, token) { state.token = token; localStorage.setItem('token', token) axios.defaults.headers.common.Authorization = `Bearer `+token; }, clearUserData () { localStorage.removeItem('token') location.reload() } }, actions: {}, modules: {} });
main.js
不用再添加拦截器
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现