express - 正确格式化来自 VueJS 的身份验证请求对象
问题描述
我有一个使用 express/postgres api 的 VueJS/Vuex 前端。
在 Postman 中,注册和登录都使用如下请求:
{ "user": { "email": "user@gmail", "password":...}}
从 Vue 应用程序中,注册按预期工作,但用于登录,而不是发送请求对象,如
{ "user": { "email": "user@gmail", "password":...}}
,这是 api 所期望的,它只发送,
{ "email": "user@gmail", "password":...}
这导致 api 抛出:
TypeError:无法读取未定义的属性“电子邮件”
这是我的登录组件:
<template>
<div class="ui stackable three column centered grid container">
<div class="column">
<h2 class="ui dividing header">Log In</h2>
<Notification
:message="notification.message"
:type="notification.type"
v-if="notification.message"
/>
<form class="ui form" @submit.prevent="login">
<div class="field">
<label>Email</label>
<input type="email" name="email" v-model="email" placeholder="Email" required>
</div>
<div class="field">
<label>Password</label>
<input type="password" name="password" v-model="password" placeholder="Password" required>
</div>
<button class="fluid ui primary button">LOG IN</button>
<div class="ui hidden divider"></div>
</form>
<div class="ui divider"></div>
<div class="ui column grid">
<div class="center aligned column">
<p>
Don't have an account? <router-link to="/signup">Sign Up</router-link>
</p>
</div>
</div>
</div>
</div>
</template>
<script>
import Notification from '@/components/Notification'
export default {
name: 'LogIn',
components: {
Notification
},
data () {
return {
email: '',
password: '',
notification: {
message: '',
type: ''
}
}
},
// beforeRouteEnter (to, from, next) {
// const token = localStorage.getItem('tweetr-token')
// return token ? next('/') : next()
// },
methods: {
login () {
this.$store
.dispatch('login', {
email: this.email,
password: this.password
})
.then(() => {
console.log(this.$store.user)
// redirect to user home
this.$router.push('/')
})
.catch(error => console.log(error))
}
}
}
</script>
这是我的 store.js:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
// import SubscriptionsService from './services/SubscriptionsService'
Vue.use(Vuex)
const VUE_APP_ROOT_API = 'http://localhost:8000'
export default new Vuex.Store({
state: {
status: '',
user: JSON.parse(localStorage.getItem('user'))
},
mutations: {
auth_request (state) {
state.status = 'Signing in...'
},
set_user (state, user) {
state.user = user
localStorage.setItem('user', JSON.stringify(user))
console.log(user)
},
auth_success (state) {
state.status = 'success'
},
auth_error (state) {
state.status = 'Invalid credentials'
},
logout (state) {
state.status = ''
state.user = null
localStorage.removeItem('user')
}
},
actions: {
register ({ commit }, user) {
return new Promise((resolve, reject) => {
commit('auth_request')
console.log(process.env.VUE_APP_ROOT_API)
axios({ url: VUE_APP_ROOT_API + '/api/auth', data: user, method: 'POST' })
.then(async resp => {
const user = resp.data.user
commit('auth_success')
commit('set_user', user)
resolve(resp)
})
.catch(err => {
commit('auth_error', err)
localStorage.removeItem('token')
reject(err)
})
})
},
login ({ commit }, user) {
return new Promise((resolve, reject) => {
commit('auth_request')
console.log(user);
axios({ url: VUE_APP_ROOT_API + '/api/auth/login', data: user, method: 'POST' })
.then(resp => {
const user = resp.data.user
// console.log(user)
// console.log(resp)
commit('auth_success')
commit('set_user', user)
resolve(resp)
})
.catch(err => {
commit('auth_error')
commit('logout')
reject(err)
})
})
},
logout ({ commit }) {
return new Promise((resolve) => {
commit('logout')
localStorage.removeItem('token')
delete axios.defaults.headers.common['authorization']
resolve()
})
}
},
getters: {
isAuthenticated: state => !!state.user,
authStatus: state => state.status,
user: state => state.user
}
})
为了比较,这是我的工作注册组件:
<template>
<div class="ui stackable three column centered grid container">
<div class="column">
<h2 class="ui dividing header">Sign Up, it's free!</h2>
<form class="ui form" @submit.prevent="signup">
<div class="field">
<label>Username</label>
<input type="username" name="username" v-model="username" placeholder="Username">
</div>
<div class="field">
<label>Email</label>
<input type="email" name="email" v-model="email" placeholder="Email">
</div>
<div class="field" >
<label>Password</label>
<input type="password" name="password" v-model="password" placeholder="Password">
</div>
<button class="fluid ui primary button">SIGN UP</button>
<div class="ui hidden divider"></div>
</form>
<div class="ui divider"></div>
<div class="ui column grid">
<div class="center aligned column">
<p>
Got an account? <router-link to="/login">Log In</router-link>
</p>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'SignUp',
data () {
return {
email: '',
password: '',
username: '',
notification: {
message: '',
type: ''
}
}
},
methods: {
signup: function () {
let data = {
user: {
email: this.email,
password: this.password,
username: this.username
}
}
this.$store.dispatch('register', data)
.then(() => this.$router.push('/'))
.catch(err => console.log(err))
},
}
}
</script>
如何格式化请求对象以匹配 api 的期望?
解决方案
尝试以与您的注册功能类似的结构发送有效负载:
.dispatch('login', {
user: {
email: this.email,
password: this.password
}
})
推荐阅读
- jackson - 记录自定义数据映射
- excel - 计算逗号分隔列表中的奇数和偶数
- neural-network - Pytorch minibatching 使模型无法训练
- ruby-on-rails - 如何在同一台服务器上部署单独的 Rails API 后端和 React 前端
- javascript - 如何使用 this 关键字向构造函数添加新属性?
- gcc - 如何编译 VBScript 以包含 DLL 处理程序?
- php - 如何在 Laravel 中使用 select 获取相关字段值?
- python-3.x - 如何更正输入提示中大括号的显示?
- mysql - MySql如何根据查询类型创建一行并添加子表?
- dataset - SSRS textrun 在外部聚合中使用第一个聚合(不同的数据集)