Laravel+SSR实现保存登录状态(步骤详解)

本篇文章给大家带来了关于Laravel+SSR的相关知识,其中主要介绍了有关Laravel SSR 下是如何保存登录状态的,感兴趣的朋友,下面一起来看一下,希望对大家有帮助。

基于 Laravel + Nuxt3 的在线 Demo(https://laravel-nuxt3.ruti.page/)

Laravel + SSR nuxt: 如何保存登录状态?

Laravel + 客户端渲染的 Vue 确实写起来比较快,但是我们有些时候确实很需要 SEO,比如说电商、门户网站、论坛;而且对于大型项目,相比起客户端渲染,服务器端渲染带来的首屏加载时间上的优势确实是碾压的。

但是很多同学卡在了 SSR 下如何保存登录状态 这个问题下面,即如何像传统的 PHP/JSP 页面那样,刷新页面后仍保有登录状态

准备工作

首先准备 2 个接口,一个是

GET http://example.com/api/auth/user

用户获取当前登录用户信息

POST http://example.com/api/auth/tokens

用于请求授权

这里有一个包含 GitHub OAuth 的完整例子 ? laravel-nuxt3-api,并且测试覆盖率是 100%

f8d4b9b01b181c0b8a147de99c9c3b0.jpg

开始 SSR

  • Nuxt3

在 Nuxt3 中,可以很自由地创建一个 server only 的脚本,在 initial 整个 Nuxt App 时,可以在渲染 html 前执行这个 server only 的脚本,并在渲染 html 时使用其返回的结果。

我们可以在 plugins 下面创建一个 *.server.[js|ts] 的 server only 的脚本,

plugins/init.server.js

import { defineNuxtPlugin } from '#app';
import { useAuth } from '~/store/auth.js';
function cookieFromRequestHeaders (key) {
    const headers = useRequestHeaders(['cookie']);
    if ('cookie' in headers) {
        const cookie = headers.cookie.split(';').find(
            c => c.trim().startsWith(`${key}=`)
        );
        if (cookie) {
            return cookie.split('=')[1];
        }
    }
    return '';
}
export default defineNuxtPlugin(async (nuxtApp) => {
    const token = cookieFromRequestHeaders('token');
    if (token) {
        const auth = useAuth(nuxtApp.$pinia);
        auth.setToken(token);
        await auth.fetchUser();
    }
});

在 store/auth.js 定义管理全局状态的 pinia,并在其中发送异步请求

import { defineStore } from 'pinia';
import { useCustomFetch } from '~/composables/useCustomFetch.js';
import cookie from 'js-cookie';
export const useAuth = defineStore('auth', {
    state: () => ({
        _token: '',
        _user: {},
    }),
    getters: {
        token() {
            return this._token;
        },
        user() {
            return this._user;
        },
    },
    actions: {
        async fetchUser() {
            const { data, error } = await useCustomFetch('/auth/user');
            if (error.value) {
                this.reset();
            }
            else {
                this.setUser(data.value);
            }
        },
        // ...
    },
});

注意: Nuxt3 中不推荐使用 axios 等第三方的 http 包,而是使用其内置的 useFetch()

完整的例子 ? laravel-nuxt3-web

  • Nuxt2

在 Nuxt2 中,不同于 Nuxt3,Nuxt2 只能在 store/index.js 中的 nuxtServerInit() 中运行 server only 的脚本(但是这里我们可以使用 axios)

store/index.js

export const actions = {
    nuxtServerInit({ commit, dispatch, route }, { req }){
        const token = cookieFromRequest(req, 'token');
        if (!!token) {
            commit('auth/setToken', token);
        }
    }
};

store/auth.js

import Cookie from 'js-cookie';
export const state = () => ({
    user: null,
    token: null
});
export const getters = {
    user: state => state.user,
    token: state => state.token,
    check: state => state.user !== null
};
export const mutations = {
    setToken(state, token){
        state.token = token;
    },
    fetchUserSuccess(state, user){
        state.user = user;
    },
    fetchUserFailure(state){
        state.user = null;
    },
    logout(state){
        state.token = null;
        state.user = null;
    },
    updateUser(state, { user }){
        state.user = user;
    }
}
export const actions = {
    saveToken({ commit }, { token, remember }){
        commit('setToken', token);
        Cookie.set('token', token);
    },
    async fetchUser({ commit }){
        try{
            const { data } = await this.$axios.get('/auth/user');
            commit('fetchUserSuccess', data);
        }catch(e){
            Cookie.remove('token');
            commit('fetchUserFailure');
        }
    },
    // ...
}

更完整的代码 ? Nuxt middleware to check if user is logged in not working

推荐学习:《laravel视频教程》

以上就是Laravel+SSR实现保存登录状态(步骤详解)的详细内容,更多请关注其它相关文章!