如何在前端通过Laravel Passport为用户传递Access Token并进入客户端面板
嘿,看起来你已经把Laravel Passport服务端和客户端的核心配置都搞定了,甚至用Postman验证过授权流程,接下来就是前端怎么处理拿到的token、完成用户授权并进入面板对吧?我来给你捋捋最实用的实操步骤:
前端处理Laravel Passport Access Token的完整流程
你已经拿到了授权返回的token_type、access_token等信息,接下来核心要做的就是安全存储token、自动携带token发起请求、控制页面权限跳转这三件事。
1. 安全存储Access Token
首先得把拿到的token存起来,常用的存储方案各有优劣,你可以根据自己的场景选:
- localStorage:持久化存储,关闭浏览器再打开token还在,但有XSS窃取风险(如果你的前端做了足够的XSS防护可以用)。
- sessionStorage:会话级存储,关闭浏览器就失效,安全性稍高,但用户刷新页面会丢失token。
- HttpOnly Cookie:最安全的方式,JS无法读取,能避免XSS窃取,但需要服务端配合设置跨域Cookie(如果是跨域场景)。
举个localStorage存储的简单例子:
// 假设你用axios/fetch拿到了授权接口的返回值 const authResponse = await axios.post('你的Passport授权地址', { grant_type: 'password', // 或者你用的授权类型,比如authorization_code client_id: '你的客户端ID', client_secret: '你的客户端密钥', username: 用户输入的账号, password: 用户输入的密码 }); // 存储token及过期时间 localStorage.setItem('access_token', authResponse.data.access_token); localStorage.setItem('refresh_token', authResponse.data.refresh_token); // 计算过期时间戳,方便后续自动刷新 localStorage.setItem('token_expires_at', Date.now() + authResponse.data.expires_in * 1000);
2. 自动携带Token发起API请求
前端每次调用客户端(或Passport服务端)的API时,需要在请求头里带上Authorization: Bearer {access_token}。用axios的话可以设置全局拦截器,一劳永逸:
import axios from 'axios'; // 创建专属的API请求实例 const apiClient = axios.create({ baseURL: '你的客户端API基础地址', }); // 请求拦截器:自动给每个请求加token apiClient.interceptors.request.use(config => { const token = localStorage.getItem('access_token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => Promise.reject(error)); // 响应拦截器:处理token过期的情况 apiClient.interceptors.response.use( response => response, async error => { // 如果返回401 Unauthorized,说明token失效了 if (error.response?.status === 401) { const refreshToken = localStorage.getItem('refresh_token'); try { // 调用Passport的刷新token接口 const refreshResponse = await axios.post('你的Passport刷新token地址', { grant_type: 'refresh_token', refresh_token: refreshToken, client_id: '你的客户端ID', client_secret: '你的客户端密钥', }); // 更新本地存储的新token localStorage.setItem('access_token', refreshResponse.data.access_token); localStorage.setItem('token_expires_at', Date.now() + refreshResponse.data.expires_in * 1000); // 重新发起原来的请求 error.config.headers.Authorization = `Bearer ${refreshResponse.data.access_token}`; return axios(error.config); } catch (refreshError) { // 刷新失败,直接跳回登录页 localStorage.clear(); window.location.href = '/login'; } } return Promise.reject(error); } ); export default apiClient;
3. 页面跳转与权限控制
拿到token并存储后,就可以跳转到客户端面板了,同时要给页面加权限校验,避免未登录用户直接访问面板:
登录成功后跳转
// 登录请求成功后 await axios.post('你的授权地址', loginFormData); // 存储token(参考步骤1) localStorage.setItem('access_token', authResponse.data.access_token); // 跳转到面板页面 window.location.href = '/dashboard';
面板页面的权限拦截
如果用Vue,可以在路由守卫里做校验:
router.beforeEach((to, from, next) => { // 判断当前路由是否需要授权 const requiresAuth = to.matched.some(record => record.meta.requiresAuth); const hasToken = !!localStorage.getItem('access_token'); if (requiresAuth && !hasToken) { // 未登录,跳回登录页 next('/login'); } else { next(); } }); // 路由配置示例 const routes = [ { path: '/login', component: LoginPage }, { path: '/dashboard', component: DashboardPage, meta: { requiresAuth: true } }, ];
如果用React,可以写一个私有路由组件:
function PrivateRoute({ children, ...rest }) { const hasToken = !!localStorage.getItem('access_token'); return ( <Route {...rest} render={({ location }) => hasToken ? ( children ) : ( <Redirect to={{ pathname: '/login', state: { from: location } }} /> ) } /> ); } // 使用示例 <Router> <Switch> <Route path="/login" component={Login} /> <PrivateRoute path="/dashboard"> <Dashboard /> </PrivateRoute> </Switch> </Router>
4. 退出登录的处理
退出时要清除本地存储的所有token,然后跳回登录页:
function handleLogout() { localStorage.removeItem('access_token'); localStorage.removeItem('refresh_token'); localStorage.removeItem('token_expires_at'); window.location.href = '/login'; }
额外注意事项
- 用localStorage的时候一定要做好XSS防护,比如对用户输入做转义、开启CSP等,避免token被窃取。
- 如果是跨域场景,服务端要配置好CORS,允许客户端域名访问;如果用Cookie存储token,要设置
withCredentials: true并配置跨域Cookie参数。 - 可以在页面初始化时检查token是否过期,提前触发刷新逻辑,提升用户体验。
内容的提问来源于stack exchange,提问作者Gabrielle-M
相关产品推荐
相关产品推荐

