Udemy - Nuxt JS with Laravel API - Building SSR Vue JS Apps 笔记11 Nuxt - Authentication
Nuxt Auth Setup
参考 https://auth.nuxtjs.org/#getting-started
执行:
npm install @nuxtjs/auth @nuxtjs/axios
nuxt.config.js修改:
export default {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{hid: 'description', name: 'description', content: process.env.npm_package_description || ''}
],
link: [
{rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'},
{rel: 'stylesheet', href: 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css'},
],
script: [
{src: 'https://code.jquery.com/jquery-3.5.1.slim.min.js', type: 'text/javascript'},
{src: 'https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js', type: 'text/javascript'},
{src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js', type: 'text/javascript'},
]
},
/*
** Customize the progress-bar color
*/
loading: {color: '#fff'},
/*
** Global CSS
*/
css: [
'@/assets/styles/main.css',
],
/*
** Plugins to load before mounting the App
*/
plugins: [],
/*
** Nuxt.js dev-modules
*/
buildModules: [],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios',
'@nuxtjs/auth',
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
baseURL: "http://backend.test/api",
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {
}
},
auth: {
// Options
}
}
然后参考https://auth.nuxtjs.org/schemes/local.html#options 设置nuxt.config.js中的 auth option
官方文档中有
最为官方推荐的最佳实践,加上还是可以的。
export default {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{hid: 'description', name: 'description', content: process.env.npm_package_description || ''}
],
link: [
{rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'},
{rel: 'stylesheet', href: 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css'},
],
script: [
{src: 'https://code.jquery.com/jquery-3.5.1.slim.min.js', type: 'text/javascript'},
{src: 'https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js', type: 'text/javascript'},
{src: 'https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js', type: 'text/javascript'},
]
},
/*
** Customize the progress-bar color
*/
loading: {color: '#fff'},
/*
** Global CSS
*/
css: [
'@/assets/styles/main.css',
],
/*
** Plugins to load before mounting the App
*/
plugins: [],
/*
** Nuxt.js dev-modules
*/
buildModules: [],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios',
'@nuxtjs/auth',
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
baseURL: "http://backend.test/api",
},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {
}
},
auth: {
// Options
strategies: {
local: {
endpoints: {
login: {url: 'login', method: 'post', propertyName: 'meta.token'},
user: {url: 'user', method: 'get', propertyName: 'data'},
logout: {url: 'logout', method: 'post'},
}
}
}
}
}
添加store/index.js文件,代码暂时留空。
User Login – Nuxt
修改login.vue:
<template> <div class="container col-md-6 mt-5"> <h2>Login</h2> <br> <form @submit.prevent="submit"> <div class="form-group"> <label>Email address</label> <input type="email" class="form-control" v-model.trim="form.email" autofocus> <small class="form-text text-danger">Show errors here</small> </div> <div class="form-group"> <label>Password</label> <input type="password" class="form-control" v-model.trim="form.password" autofocus> <small class="form-text text-danger">Show errors here</small> </div> <button type="submit" class="btn btn-primary">Login</button> </form> <br> <p>Don't have an account? <nuxt-link to="/register">Register</nuxt-link> </p> </div> </template> <script> export default { name: "login", data() { return { form: { email: '', password: '', } } }, methods: { async submit() { await this.$auth.loginWith('local', { data: this.form, }); this.$router.push('/'); }, } } </script> <style scoped> </style>
打开 http://localhost:3000/login 测试登录:
可以看到 发起了login request
以及一个user request
而vuex中状态:
有了一个auth Object, loggedIn也为true,user也有一个Object了。
local storage中的strategy值为true,可以看到auth_token也存储好了。
在其请求user的时候,会自动配置Bearer token:
尝试清空site data
然后刷新页面,查看vuex状态:
user object清空了,loggedIn也变成了false。
未清空site data的话,刷新会是这样的:
Auth Getters
修改store/index.js文件:
export const getters = {
authenticated(state) {
return state.auth.loggedIn;
},
user(state) {
return state.auth.user;
}
}
Navbar.vue中获取auth状态判断是否展示login register按钮;
测试一下:
<template> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <nuxt-link to="/" class="navbar-brand">Frontend</nuxt-link> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> <nuxt-link class="nav-link" to="/">Home</nuxt-link> </li> <li class="nav-item"> <nuxt-link class="nav-link" to="/">Posts</nuxt-link> </li> </ul> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <nuxt-link class="nav-link" to="/login">Login</nuxt-link> </li> <li class="nav-item"> <nuxt-link class="nav-link" to="/register">Register</nuxt-link> </li> </ul> </div> {{loggedIn}} </nav> </template> <script> import {mapGetters} from 'vuex'; export default { name: "Navbar", computed: { ...mapGetters({ loggedIn: "authenticated", }) } } </script> <style scoped> </style>
结果:
测试完效果后,删除
Global Mixin
新建plugins/mixins/user.js
import Vue from 'vue';
import {mapGetters} from 'vuex';
const User = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
user: 'user',
authenticated: "authenticated",
})
}
})
}
};
Vue.use(User);
然后再nuxt.config.js中注册这个plugin
因为mixin注册好了,所以npm run dev 之后我们就可以使用了。
再在Navbar.vue中测试一下:
Show User
修改Navbar.vue:
<template> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <nuxt-link to="/" class="navbar-brand">Frontend</nuxt-link> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav"> <li class="nav-item active"> <nuxt-link class="nav-link" to="/">Home</nuxt-link> </li> <li class="nav-item"> <nuxt-link class="nav-link" to="/">Posts</nuxt-link> </li> </ul> <template v-if="!authenticated"> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <nuxt-link class="nav-link" to="/login">Login</nuxt-link> </li> <li class="nav-item"> <nuxt-link class="nav-link" to="/register">Register</nuxt-link> </li> </ul> </template> <template v-else> <ul class="navbar-nav ml-auto"> <li class="nav-item"> <a class="nav-link">{{user.name}}</a> </li> <li class="nav-item"> <a class="nav-link">Logout</a> </li> </ul> </template> </div> </nav> </template> <script> export default { name: "Navbar", } </script> <style scoped> </style>
user是mixin中已经全局注册了的,所以直接可以使用。
Logout User
在Navbar.vue中添加:
点击logout前:
点击logout
User Register – Nuxt
修改pages/register.vue:
<template> <div class="container col-md-6 mt-5"> <h2>Register</h2> <br> <form @submit.prevent="submit"> <div class="form-group"> <label>UserName</label> <input type="text" class="form-control" placeholder="Enter your Username" v-model.trim="form.name" autofocus> <small class="form-text text-danger">Show errors here</small> </div> <div class="form-group"> <label>Email address</label> <input type="email" class="form-control" placeholder="Enter your email address" v-model.trim="form.email"> <small class="form-text text-danger">Show errors here</small> </div> <div class="form-group"> <label>Password</label> <input type="password" class="form-control" placeholder="Enter your password" v-model.trim="form.password"> <small class="form-text text-danger">Show errors here</small> </div> <div class="form-group"> <label>Confirm Password</label> <input type="password" class="form-control" placeholder="Confirm your password" v-model.trim="form.password_confirmation"> <small class="form-text text-danger">Show errors here</small> </div> <button type="submit" class="btn btn-primary">Register</button> </form> <br> <p>Already have an account? <nuxt-link to="/login">Login</nuxt-link> </p> </div> </template> <script> export default { name: "register", data() { return { form: { name: '', email: '', password: '', password_confirmation: '', } } }, methods: { async submit() { await this.$axios.$post('register', this.form); this.$auth.loginWith('local', { data: { email: this.form.email, password: this.form.password, } }); //redirect this.$router.push('/'); } } } </script> <style scoped> </style>
效果如下:
源代码:https://github.com/dzkjz/laravel-backend-nuxt-frontend-frontpart
选择:

























浙公网安备 33010602011771号