博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue中使用vuex_使用Vuex在Vue中处理身份验证
阅读量:2521 次
发布时间:2019-05-11

本文共 17155 字,大约阅读时间需要 57 分钟。

vue中使用vuex

Traditionally, many people use local storage to manage tokens generated through client-side authentication. A big concern is always a better way to manage authorization tokens to allow us to store even more information on users.

传统上,许多人使用本地存储来管理通过客户端身份验证生成的令牌。 人们始终关心的一个更好的方法是管理授权令牌,以使我们能够在用户上存储更多信息。

This is where comes in. Vuex manages states for applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion.

这就是进入的地方管理应用程序的状态。 它充当应用程序中所有组件的集中存储,其规则确保状态只能以可预测的方式进行更改。

Sounds like a better alternative to always checking localStorage? Let’s explore it.

听起来像是始终检查localStorage的更好的选择? 让我们来探索它。

( )

  1. Knowledge of JavaScript

    JavaScript知识
  2. Node installed on your local system

    安装在本地系统上的节点
  3. Knowledge of Vue

    Vue知识
  4. Have installed

    安装了
  5. Have read

    已阅读

( )

For this project, we want to create a vue application that has vuex and . We will use the vue cli 3.0 to create a new vue project and select router and vuex from the options.

对于此项目,我们要创建一个具有vuex和的vue应用程序。 我们将使用vue cli 3.0创建一个新的vue项目,并从选项中选择router和vuex。

Run the following command to set it up:

运行以下命令进行设置:

$ vue create vue-auth

Follow the dialogue that shows up, add the necessary information and select the options we need and complete the installation.

按照出现的对话框,添加必要的信息,然后选择我们需要的选项并完成安装。

Next, install :

接下来,安装 :

$npm install axios --save

设置Axios (Setup Axios)

We will need axios across many of our components. Let’s set it up at the entry level so we do not have to import it every time we need it.

我们将需要在许多组件中使用axios。 让我们在入门级进行设置,这样就不必每次都需要导入它。

Open the ./src/main.js file and add the following:

打开./src/main.js文件并添加以下内容:

[...]import store from './store'import Axios from 'axios'Vue.prototype.$http = Axios;const token = localStorage.getItem('token')if (token) {
Vue.prototype.$http.defaults.headers.common['Authorization'] = token}[...]

Now, when we want to use axios inside our component, we can do this.$http and it will be like calling axios directly. We also set the Authorization on axios header to our token, so our requests can be processed if a token is required. This way, we do not have to set token anytime we want to make a request.

现在,当我们想在组件内部使用axios时,可以执行this.$http就像直接调用axios。 我们还将axios标头上的Authorization设置为令牌,因此如果需要令牌,则可以处理我们的请求。 这样,我们不必在要发出请求的任何时间设置令牌。

When that is done, let’s set up the server to handle authentication.

完成后,让我们设置服务器以处理身份验证。

( )

I already wrote about this when explaining how to handle authentication with vue-router. Check out the section of this

在解释如何使用vue-router进行身份验证时,我已经写过有关此内容的文章。 查看本节的“ 部分

( )

登录组件 (The Login Component)

Create a file Login.vue in the ./src/components directory. Then, add the template for the login page:

./src/components目录中创建一个文件Login.vue 。 然后,为登录页面添加模板:

When you are done, add the data attributes that would bind to the HTML form:

完成后,添加将绑定到HTML表单的数据属性:

[...]

Now, let’s add the method for handling login:

现在,让我们添加用于处理登录的方法:

[...]

We are using a vuex action — login to handle this authentication. We can resolve actions into promises so we can do cool things with them inside our component.

我们正在使用vuex操作- login以处理此身份验证。 我们可以将行动分解为承诺,这样我们就可以在组件内部用它们来做一些很棒的事情。

寄存器组件 (The Register Component)

Like the component for login, let’s make one for registering users. Start by creating a file Register.vue in the components directory and add the following to it:

像用于登录的组件一样,让我们​​制作一个用于注册用户的组件。 首先在components目录中创建一个文件Register.vue ,并将以下内容添加到其中:

Let define the data attributes we will bind to the form:

让我们定义将绑定到表单的数据属性:

[...]

Now, let’s add the method for handling login:

现在,让我们添加用于处理登录的方法:

[...]

安全组件 (The Secure Component)

Let’s make a simple component that would only display if our user is authenticated. Create the component file Secure.vue and add the following to it:

让我们做一个简单的组件,该组件仅在我们的用户通过身份验证时才会显示。 创建组件文件Secure.vue并添加以下内容:

更新应用程序组件 (Update The App Component)

Open ./src/App.vue file and add the following to it:

打开./src/App.vue文件,然后向其中添加以下内容:

Can you see the Logout link we set to only show up if a user is logged in? Great.

您能看到我们设置为仅在用户登录后才显示的Logout链接吗? 大。

Now, let’s add the logic behind the log out:

现在,让我们在注销后添加逻辑:

We are doing two things — computing the authentication state of the user and dispatching a logout action to our vuex store when a user clicks the logout button. After the log out, we send the user to login page using this.$router.push('/login'). You can change where the user gets sent to if you want.

我们正在做两件事–计算用户的身份验证状态,并在用户单击注销按钮时将注销操作分派到我们的vuex存储。 注销后,我们使用this.$router.push('/login')将用户发送到login页面。 您可以根据需要更改将用户发送到的位置。

That’s it. Let’s make the auth module using vuex.

而已。 让我们使用vuex创建auth模块。

( )

If you read past the ****section, you would notice we had to store user auth token in localStorage and we had to retrieve both the token and user information anytime we wanted to check if the user is authenticated. This works, but it is not really elegant. We will rebuild the authentication to use vuex.

如果您阅读了 ****部分的内容,您会发现我们必须将用户身份验证令牌存储在localStorage中,并且无论何时要检查用户是否已通过身份验证,都必须同时检索令牌和用户信息。 这行得通,但并不是很优雅。 我们将重建身份验证以使用vuex。

First, let’s setup our store.js file for vuex:

首先,让我们为vuex设置store.js文件:

import Vue from 'vue'import Vuex from 'vuex'import axios from 'axios'Vue.use(Vuex)export default new Vuex.Store({
state: {
status: '', token: localStorage.getItem('token') || '', user : {
} }, mutations: {
}, actions: {
}, getters : {
}})

If you noticed, we have imported vue, vuex and axios, then asked vue to use vuex. This is because we mean serious business here.

如果您注意到,我们已经导入了vue,vuex和axios,然后要求vue使用vuex。 这是因为我们的意思是认真的生意。

We have defined the attributes of the state. Now the vuex state would hold our authentication status, jwt token and user information.

我们已经定义了状态的属性。 现在,vuex状态将保留我们的身份验证状态, jwt令牌和用户信息。

创建Vuex login操作 (Create The Vuex login Action)

Vuex actions are used to commit mutations to the vuex store. We will create a login action that would authenticate a user with the server and commit user credentials to the vuex store. Open the ./src/store.js file and add the following to actions object:

Vuex操作用于将变异提交到vuex存储。 我们将创建一个login操作,该操作将对服务器进行用户身份验证并将用户凭据提交给vuex存储。 打开./src/store.js文件,并将以下内容添加到action对象:

login({
commit}, user){
return new Promise((resolve, reject) => {
commit('auth_request') axios({
url: 'http://localhost:3000/login', data: user, method: 'POST' }) .then(resp => {
const token = resp.data.token const user = resp.data.user localStorage.setItem('token', token) axios.defaults.headers.common['Authorization'] = token commit('auth_success', token, user) resolve(resp) }) .catch(err => {
commit('auth_error') localStorage.removeItem('token') reject(err) }) })},

The login action passes vuex commit helper that we will use to trigger mutations. Mutations make changes to vuex store.

登录操作传递了vuex commit助手,我们将使用它来触发突变。 变异会更改vuex存储。

We are making a call to the server’s login route and returning the necessary data. We store the token on localStorage, then pass the token and user information to auth_success to update the store’s attributes. We also set the header for axios at this point as well.

我们正在拨打服务器的登录路由,并返回必要的数据。 我们将令牌存储在localStorage上,然后将令牌和用户信息传递给auth_success来更新商店的属性。 在这一点上,我们还为axios设置了标头。

We could store the token in vuex store, but if the user leaves our application, all of the data in the vuex store disappears. To ensure we allow the user to return to the application within the validity time of the token and not have to log in again, we have to keep the token in localStorage.

我们可以将令牌存储在vuex存储中,但是如果用户离开我们的应用程序,则vuex存储中的所有数据都会消失。 为确保我们允许用户在令牌的有效期内返回应用程序而不必再次登录,我们必须将令牌保留在localStorage中。

It’s important you know how these work so you can decide what exactly it is you want to achieve.

了解这些工作原理非常重要,这样您就可以决定要实现的目标。

We return a promise so we can return a response to a user after login is complete.

我们返回承诺,因此我们可以在登录完成后将响应返回给用户。

创建Vuex register操作 (Create The Vuex register Action)

Like the login action, the register action will work almost the same way. In the same file, add the following in the actions object:

login操作一样, register操作的工作方式几乎相同。 在同一文件中,在action对象中添加以下内容:

register({
commit}, user){
return new Promise((resolve, reject) => {
commit('auth_request') axios({
url: 'http://localhost:3000/register', data: user, method: 'POST' }) .then(resp => {
const token = resp.data.token const user = resp.data.user localStorage.setItem('token', token) axios.defaults.headers.common['Authorization'] = token commit('auth_success', token, user) resolve(resp) }) .catch(err => {
commit('auth_error', err) localStorage.removeItem('token') reject(err) }) })},

This works similarly to login action, calling the same mutators as our login and register actions have the same simple goal — get a user into the system.

这与login操作类似,其调用方式与我们的loginregister操作具有相同的简单目标—使用户进入系统。

创建Vuex logout操作 (Create The Vuex logout Action)

We want the user to have the ability to log out of the system, and we want to destroy all data created during the last authenticated session. In the same actions object, add the following:

我们希望用户具有注销系统的能力,并且希望销毁在上次身份验证会话期间创建的所有数据。 在同一actions对象中,添加以下内容:

logout({
commit}){
return new Promise((resolve, reject) => {
commit('logout') localStorage.removeItem('token') delete axios.defaults.headers.common['Authorization'] resolve() })}

Now, when the user clicks to log out, we will remove the jwt token we stored along with the axios header we set. There is no way they can perform a transaction requiring a token now.

现在,当用户单击注销时,我们将删除存储的jwt令牌以及设置的axios标头。 他们现在无法执行需要令牌的交易。

创建变异 (Create The Mutations)

Like I mentioned earlier, mutators are used to change the state of a vuex store. Let’s define the mutators we had used throughout our application. In the mutators object, add the following:

就像我之前提到的那样,mutator用于更改vuex存储的状态。 让我们定义在整个应用程序中使用的转换器。 在mutators对象中,添加以下内容:

mutations: {
auth_request(state){
state.status = 'loading' }, auth_success(state, token, user){
state.status = 'success' state.token = token state.user = user }, auth_error(state){
state.status = 'error' }, logout(state){
state.status = '' state.token = '' },},

创建吸气剂 (Create The Getters)

We use getter to get the value of the attributes of vuex state. The role of our getter in the situation is to separate application data from application logic and ensure we do not give away sensitive information.

我们使用getter获取vuex状态的属性值。 在这种情况下,我们的吸气剂的作用是将应用程序数据与应用程序逻辑分开,并确保我们不会泄露敏感信息。

Add the following to the getters object:

将以下内容添加到getters对象:

getters: {
isLoggedIn: state => !!state.token, authStatus: state => state.status,}

You would agree with me that this is a neater way to access data in the store ☺️.

您会同意我的看法,这是一种访问商店☺️中的数据的更整洁的方式。

( )

The whole purpose of this article is to implement authentication and keep certain pages away from a user who is not authentication. To achieve this, we need to know the page the user wants to visit and equally have a way to check if the user is authenticated. We also need a way to say if the page is reserved for only authenticated user or unauthenticated user alone or both. These things are important considerations which, luckily, we can achieve with vue-router.

本文的全部目的是实现身份验证,并使某些页面远离非身份验证用户。 为此,我们需要知道用户想要访问的页面,并且同样具有一种检查用户是否已通过身份验证的方法。 我们还需要一种方法来说明页面是仅保留给已认证的用户还是仅保留给未认证的用户,或者两者都保留。 这些东西是重要的考虑因素,幸运的是,我们可以使用vue-router实现这些考虑。

定义经过身份验证和未经身份验证的页面的路由 (Defiing Routes For Authenticated And Unauthenticated Pages)

Open the ./src/router.js file and import what we need for this setup:

打开./src/router.js文件,并导入此设置所需的内容:

import Vue from 'vue'import Router from 'vue-router'import store from './store.js'import Home from './views/Home.vue'import About from './views/About.vue'import Login from './components/Login.vue'import Secure from './components/Secure.vue'import Register from './components/Register.vue'Vue.use(Router)

As you can see, we have imported vue, vue-router and our vuex store setup. We also imported all the components we defined and set vue to use our router.

如您所见,我们已经导入了vue,vue-router和我们的vuex存储设置。 我们还导入了我们定义的所有组件,并设置了vue以使用我们的路由器。

Let’s define the routes:

让我们定义路线:

[...]let router = new Router({
mode: 'history', routes: [ {
path: '/', name: 'home', component: Home }, {
path: '/login', name: 'login', component: Login }, {
path: '/register', name: 'register', component: Register }, {
path: '/secure', name: 'secure', component: Secure, meta: {
requiresAuth: true } }, {
path: '/about', name: 'about', component: About } ]})export default router

Our route definition is simple. For routes requiring authentication, we add extra data to it to enable us identify it when the user tries to access it. This is the essence of the meta attribute added to the route definition. If you are asking ”Can I add more data to this meta and use it?” then I’m pleased to tell you that you are absolutely right ?.

我们的路线定义很简单。 对于需要身份验证的路由,我们向其中添加了额外的数据,以使我们能够在用户尝试访问它时对其进行识别。 这是添加到路由定义的meta属性的本质。 如果您问“我可以向此 meta 数据添加更多数据 并使用它吗?” 那我很高兴地告诉你,你绝对正确吗?

处理未经授权的访问案例 (Handling Unauthorized Access Cases)

We have our routes defined. Now, let’s check for unauthorized access and take action. In the router.js file, add the following before the export default router:

我们定义了路线。 现在,让我们检查未经授权的访问并采取措施。 在router.js文件中,在export default router之前添加以下内容:

router.beforeEach((to, from, next) => {
if(to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
next() return } next('/login') } else {
next() }})

From the article on using vue router for authentication, you can recall we had a really complex mechanism here that grew very big and got very confusing. Vuex has helped us simplify that completely, and we can go on to add any condition to our route. In our vuex store, we can then define actions to check these conditions and getters to return them.

从有关使用vue路由器进行身份验证的文章中,您可以回忆起我们这里有一个非常复杂的机制,它变得非常大并且令人非常困惑。 Vuex帮助我们完全简化了这一过程,我们可以继续为路线添加任何条件。 然后,在我们的vuex存储中,我们可以定义操作来检查这些条件,并通过getter返回它们。

处理过期的令牌案例 (Handling Expired Token Cases)

Because we store our token in localStorage, it can remain there perpetually. This means that whenever we open our application, it would automatically authenticate a user even if the token has expired. What would happen at most is that our requests would keep failing because of an invalid token. This is bad for user experience.

因为我们将令牌存储在localStorage中,所以它可以永久保留在那里。 这意味着,每当我们打开应用程序时,即使令牌已过期,它也会自动对用户进行身份验证。 最多会发生的是,由于令牌无效,我们的请求将继续失败。 这不利于用户体验。

Now, open ./src/App.vue file and in the script, add the following to it:

现在,打开./src/App.vue文件,并在脚本中添加以下内容:

export default {
[...] created: function () {
this.$http.interceptors.response.use(undefined, function (err) {
return new Promise(function (resolve, reject) {
if (err.status === 401 && err.config && !err.config.__isRetryRequest) {
this.$store.dispatch(logout) } throw err; }); }); }}

We are intercepting axios call to determine if we get 401 Unauthorized response. If we do, we dispatch the logout action and the user gets logged out of the application. This takes them to the login page like we designed earlier and they can log in again.

我们正在拦截axios调用,以确定是否收到401 Unauthorized响应。 如果这样做,我们将分派logout操作,并且用户将从应用程序中注销。 就像我们之前设计的那样,这会将他们带到login页面,他们可以再次登录。

We can agree that this will greatly improve the user’s experience ☺️.

我们可以同意,这将大大改善用户的体验☺️。

( )

From the previous article, you can see the significant changes that get made to our present application based the introduction of vuex. Now, we do not rely on checking the token all the time and having messing conditionals everywhere we go. We can simply use the vuex store to manage authentication state and proceed to check state in our application using only a few lines of code.

从上一篇文章中,您可以看到基于vuex的引入对我们当前的应用程序进行的重大更改。 现在,我们不再依赖于一直检查令牌并在我们到处都有混乱的条件。 我们可以简单地使用vuex存储管理身份验证状态,然后仅使用几行代码就可以检查应用程序中的状态。

I hope this helps you build better applications.

我希望这可以帮助您构建更好的应用程序。

翻译自:

vue中使用vuex

转载地址:http://ssuwd.baihongyu.com/

你可能感兴趣的文章
使用jquery去掉时光轴头尾部的线条
查看>>
算法(转)
查看>>
IT职场人生系列之十五:语言与技术II
查看>>
如何在FreePBX ISO 中文版本安装讯时网关,潮流16FXS 网关和潮流话机
查看>>
基于Wolfpack开发业务监控系统
查看>>
通过Jexus 部署 dotnetcore版本MusicStore 示例程序
查看>>
程序员最常见的谎话和我自己的理解
查看>>
mine 数据
查看>>
poj2728 Desert King
查看>>
三个和尚的故事 与 项目机构管理
查看>>
Excel 日期转换
查看>>
js中的NaN、Infinity、null和undefined
查看>>
Runtime
查看>>
struts2 if标签示例
查看>>
Animate CSS
查看>>
.NET安全审核检查表
查看>>
application.properties数据库敏感信息加密这么简单?
查看>>
Language Codes: ISO 639, Microsoft and Macintosh
查看>>
centos6 x64安装elasticsearch5.5.2启动报错
查看>>
公司拷贝回家的工程用sts导入clean package报错java.lang.NoClassDefFoundError
查看>>