如何在 Vuejs 和 Node 中设置授权 header 和保护路由
How to set authorization header and protect routes in Vuejs and Node
我正在使用 passport-jwt 策略来保护我的应用程序中的授权用户,一旦我登录,我就会生成一个 jwt-token
现在我想保护我的欢迎页面路由,这样用户就无法打开它登录
所以当我登录时,我正在创建 jwt-token
和 payload
这样的
我的user.js文件
const payload = { email: rows[0].email } // jwy payload
console.log('PAYLOAD')
console.log(payload)
jwt.sign(
payload,
key.secretOrKey, { expiresIn: 3600 },
(err, token) => {
res.json({
success: true,
token: 'Bearer ' + token,
email
})
})
现在在我的passport.js我是这样做的
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
let payLoadEmail = jwt_payload.email //payload data what I have passed in creating jwt
console.log("payload email :" + payLoadEmail)
User.fetchLogedInUser(payLoadEmail)
.then(([rows]) => {
if (rows.length > 0) {
return done(null, rows[0].email) // returning data what I need
}
return done(null, false)
})
.catch(err => console.log(err))
}));
两者都工作正常。
现在我想在我的 router.js 文件中保护我的欢迎路线
const express = require('express');
const router = express.Router();
const passport = require('passport')
const UsersCtrl = require('../controllers/users');
router.use('/login', UsersCtrl.login)
router.use('/welcome',passport.authenticate('jwt',{session:false}))
router.use('/logout', UsersCtrl.logout)
module.exports = router;
假设用户类型 localhost:8080/welcome
没有登录然后我想保护它
所以在我的 store.js 文件中,当用户登录时,我在单击登录时执行此操作,并且我创建了一个方法 getAuthUser
。我不知道如何通过此配置来保护我的欢迎文件
这是我的完整 store.js 代码
import axios from 'axios'
import jwt from 'jsonwebtoken'
function checkTokenValidity(token) { // token validity
if (token) {
const decodedToken = jwt.decode(token)
return decodedToken && (decodedToken.exp * 1000) > new Date().getTime()
}
return false
}
export default {
namespaced: true,
state: {
user: null,
isAuthResolved: false // this I am calling on my login page i am confused where should I call this or not to call this
},
getters: {
authUser(state) {
return state.user
},
isAuthenticated(state) {
return !!state.user
}
},
actions: {
loginWithCredentials({ commit }, userDate) {
return axios.post('/api/v1/users/login', userDate)
.then(res => {
const user = res.data
console.log(user.email)
localStorage.setItem('jwt-token', user.token)
commit('setAuthUser', user)
})
},
logout({ commit }) {
return new Promise((resolve, reject) => {
localStorage.removeItem('jwt-token')
commit('setAuthUser', null)
resolve(true)
})
},
getAuthUser({ commit, getters }) {
const authUser = getters['authUser']
const token = localStorage.getItem('jwt-token')
const isTokenValid = checkTokenValidity(token)
if (authUser && isTokenValid) {
return Promise.resolve(authUser)
}
const config = { // here what to do with this how can I pass this to protect my route
headers: {
'cache-control': 'no-cache',
'Authorization': token
}
}
}
},
mutations: {
setAuthUser(state, user) {
return state.user = user
},
setAuthState(state, authState) {
return state.isAuthResolved = authState
}
}
在我的 route.js vue 文件中
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/welcome',
name: 'welcome',
meta: { onlyAuthUser: true },
component: () =>
import ('./views/Welcome.vue'),
}, ]
})
router.beforeEach((to, from, next) => {
store.dispatch('auth/getAuthUser')
.then((authUser) => {
const isAuthenticated = store.getters['auth/isAuthenticated']
if (to.meta.onlyAuthUser) {
if (isAuthenticated) {
next()
} else {
next({ name: 'PageNotAuthenticated' })
}
} else if (to.meta.onlyGuestUser) {
if (isAuthenticated) {
next({ name: 'welcome' })
} else {
next()
}
} else {
next()
}
})
})
export default router
我的主要问题是我想保护路由并使用 jwt 和护照对用户进行身份验证我在登录后得到 jwt 并想检查我的受保护路由是否可以访问而无需登录后端。
在前端(vue.js)我正在运行我的商店文件> getAuthUsers
我不知道如何将配置传递给其他路由,就像我的欢迎一样。
不确定我是否完全理解你的问题,因为你似乎正确地实现了路由访问。您只需将路由添加为数组,而其余代码保持不变。
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/welcome',
name: 'welcome',
meta: { onlyAuthUser: true },
component: () =>
import ('./views/Welcome.vue'),
},
{
path: '/login',
name: 'Login',
meta: { onlyGuesUser: true },
component: () =>
import ('./views/Login.vue'),
}]
})
要使用 Authentication: Bearer xxxxxxxx
,您可以修改 axios
代码以直接使用必需的 headers,而不是每次都通过路由传递它。创建一个名为 services
的新文件夹和一个名为 base-api
的文件。您当然可以随意命名,但这是我的设置。
import axios from 'axios';
export default () => {
let headers = {
'cache-control': 'no-cache'
};
let accessToken = localStorage.getItem('jwt-token');
if (accessToken && accessToken !== '') {
headers.Authorization = accessToken;
};
return axios.create({
baseURL: 'SECRET_URL_',
headers: headers
});
}
将此文件导入您的 store.js
。将 import axios from 'axios'
替换为 import axios from '@src/services/base-api.js
。由于文件正在返回一个 axios 实例,您需要以 axios()
的形式访问它。这意味着你的功能将是
return axios().post('/api/v1/users/login', userDate)
.then(res => {
// do whatever
})
我正在使用 passport-jwt 策略来保护我的应用程序中的授权用户,一旦我登录,我就会生成一个 jwt-token
现在我想保护我的欢迎页面路由,这样用户就无法打开它登录
所以当我登录时,我正在创建 jwt-token
和 payload
这样的
我的user.js文件
const payload = { email: rows[0].email } // jwy payload
console.log('PAYLOAD')
console.log(payload)
jwt.sign(
payload,
key.secretOrKey, { expiresIn: 3600 },
(err, token) => {
res.json({
success: true,
token: 'Bearer ' + token,
email
})
})
现在在我的passport.js我是这样做的
const opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = keys.secretOrKey;
passport.use(new JwtStrategy(opts, (jwt_payload, done) => {
let payLoadEmail = jwt_payload.email //payload data what I have passed in creating jwt
console.log("payload email :" + payLoadEmail)
User.fetchLogedInUser(payLoadEmail)
.then(([rows]) => {
if (rows.length > 0) {
return done(null, rows[0].email) // returning data what I need
}
return done(null, false)
})
.catch(err => console.log(err))
}));
两者都工作正常。
现在我想在我的 router.js 文件中保护我的欢迎路线
const express = require('express');
const router = express.Router();
const passport = require('passport')
const UsersCtrl = require('../controllers/users');
router.use('/login', UsersCtrl.login)
router.use('/welcome',passport.authenticate('jwt',{session:false}))
router.use('/logout', UsersCtrl.logout)
module.exports = router;
假设用户类型 localhost:8080/welcome
没有登录然后我想保护它
所以在我的 store.js 文件中,当用户登录时,我在单击登录时执行此操作,并且我创建了一个方法 getAuthUser
。我不知道如何通过此配置来保护我的欢迎文件
这是我的完整 store.js 代码
import axios from 'axios'
import jwt from 'jsonwebtoken'
function checkTokenValidity(token) { // token validity
if (token) {
const decodedToken = jwt.decode(token)
return decodedToken && (decodedToken.exp * 1000) > new Date().getTime()
}
return false
}
export default {
namespaced: true,
state: {
user: null,
isAuthResolved: false // this I am calling on my login page i am confused where should I call this or not to call this
},
getters: {
authUser(state) {
return state.user
},
isAuthenticated(state) {
return !!state.user
}
},
actions: {
loginWithCredentials({ commit }, userDate) {
return axios.post('/api/v1/users/login', userDate)
.then(res => {
const user = res.data
console.log(user.email)
localStorage.setItem('jwt-token', user.token)
commit('setAuthUser', user)
})
},
logout({ commit }) {
return new Promise((resolve, reject) => {
localStorage.removeItem('jwt-token')
commit('setAuthUser', null)
resolve(true)
})
},
getAuthUser({ commit, getters }) {
const authUser = getters['authUser']
const token = localStorage.getItem('jwt-token')
const isTokenValid = checkTokenValidity(token)
if (authUser && isTokenValid) {
return Promise.resolve(authUser)
}
const config = { // here what to do with this how can I pass this to protect my route
headers: {
'cache-control': 'no-cache',
'Authorization': token
}
}
}
},
mutations: {
setAuthUser(state, user) {
return state.user = user
},
setAuthState(state, authState) {
return state.isAuthResolved = authState
}
}
在我的 route.js vue 文件中
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/welcome',
name: 'welcome',
meta: { onlyAuthUser: true },
component: () =>
import ('./views/Welcome.vue'),
}, ]
})
router.beforeEach((to, from, next) => {
store.dispatch('auth/getAuthUser')
.then((authUser) => {
const isAuthenticated = store.getters['auth/isAuthenticated']
if (to.meta.onlyAuthUser) {
if (isAuthenticated) {
next()
} else {
next({ name: 'PageNotAuthenticated' })
}
} else if (to.meta.onlyGuestUser) {
if (isAuthenticated) {
next({ name: 'welcome' })
} else {
next()
}
} else {
next()
}
})
})
export default router
我的主要问题是我想保护路由并使用 jwt 和护照对用户进行身份验证我在登录后得到 jwt 并想检查我的受保护路由是否可以访问而无需登录后端。
在前端(vue.js)我正在运行我的商店文件> getAuthUsers
我不知道如何将配置传递给其他路由,就像我的欢迎一样。
不确定我是否完全理解你的问题,因为你似乎正确地实现了路由访问。您只需将路由添加为数组,而其余代码保持不变。
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [{
path: '/welcome',
name: 'welcome',
meta: { onlyAuthUser: true },
component: () =>
import ('./views/Welcome.vue'),
},
{
path: '/login',
name: 'Login',
meta: { onlyGuesUser: true },
component: () =>
import ('./views/Login.vue'),
}]
})
要使用 Authentication: Bearer xxxxxxxx
,您可以修改 axios
代码以直接使用必需的 headers,而不是每次都通过路由传递它。创建一个名为 services
的新文件夹和一个名为 base-api
的文件。您当然可以随意命名,但这是我的设置。
import axios from 'axios';
export default () => {
let headers = {
'cache-control': 'no-cache'
};
let accessToken = localStorage.getItem('jwt-token');
if (accessToken && accessToken !== '') {
headers.Authorization = accessToken;
};
return axios.create({
baseURL: 'SECRET_URL_',
headers: headers
});
}
将此文件导入您的 store.js
。将 import axios from 'axios'
替换为 import axios from '@src/services/base-api.js
。由于文件正在返回一个 axios 实例,您需要以 axios()
的形式访问它。这意味着你的功能将是
return axios().post('/api/v1/users/login', userDate)
.then(res => {
// do whatever
})